fosslight-util 2.1.7__py3-none-any.whl → 2.1.18__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.
@@ -27,7 +27,7 @@ def extract_name_version_from_link(link):
27
27
  origin_name = match.group(1)
28
28
  if (key == "pypi") or (key == "pypi2"):
29
29
  oss_name = f"pypi:{origin_name}"
30
- oss_name = re.sub(r"[-_.]+", "-", oss_name).lower()
30
+ oss_name = re.sub(r"[-_.]+", "-", oss_name)
31
31
  oss_version = match.group(2)
32
32
  elif key == "maven":
33
33
  artifact = match.group(2)
@@ -42,12 +42,20 @@ def extract_name_version_from_link(link):
42
42
  oss_version = match.group(2)
43
43
  elif key == "cocoapods":
44
44
  oss_name = f"cocoapods:{origin_name}"
45
+ elif key == "go":
46
+ if origin_name.endswith('/'):
47
+ origin_name = origin_name[:-1]
48
+ oss_name = f"go:{origin_name}"
49
+ oss_version = match.group(2)
50
+ elif key == "cargo":
51
+ oss_name = f"cargo:{origin_name}"
52
+ oss_version = match.group(2)
45
53
  except Exception as ex:
46
54
  logger.info(f"extract_name_version_from_link {key}:{ex}")
47
55
  if oss_name and (not oss_version):
48
- if key in ["pypi", "maven", "npm", "npm2", "pub"]:
56
+ if key in ["pypi", "maven", "npm", "npm2", "pub", "go"]:
49
57
  oss_version, link = get_latest_package_version(link, key, origin_name)
50
- logger.debug(f'Try to download with the latest version:{link}')
58
+ logger.info(f'Try to download with the latest version:{link}')
51
59
  break
52
60
  return oss_name, oss_version, link, key
53
61
 
@@ -76,8 +84,13 @@ def get_latest_package_version(link, pkg_type, oss_name):
76
84
  if pub_response.status_code == 200:
77
85
  find_version = pub_response.json().get('latest').get('version')
78
86
  link_with_version = f'https://pub.dev/packages/{oss_name}/versions/{find_version}'
87
+ elif pkg_type == 'go':
88
+ go_response = requests.get(f'https://proxy.golang.org/{oss_name}/@latest')
89
+ if go_response.status_code == 200:
90
+ find_version = go_response.json().get('Version')
91
+ link_with_version = f'https://pkg.go.dev/{oss_name}@{find_version}'
79
92
  except Exception as e:
80
- logger.debug(f'Fail to get latest package version({link}:{e})')
93
+ logger.info(f'Fail to get latest package version({link}:{e})')
81
94
  return find_version, link_with_version
82
95
 
83
96
 
@@ -98,8 +111,66 @@ def get_downloadable_url(link):
98
111
  ret, result_link = get_download_location_for_npm(new_link)
99
112
  elif pkg_type == "pub":
100
113
  ret, result_link = get_download_location_for_pub(new_link)
114
+ elif pkg_type == "go":
115
+ ret, result_link = get_download_location_for_go(new_link)
116
+ elif pkg_type == "cargo":
117
+ ret, result_link = get_download_location_for_cargo(new_link)
118
+ return ret, result_link, oss_name, oss_version, pkg_type
101
119
 
102
- return ret, result_link, oss_name, oss_version
120
+
121
+ def get_download_location_for_cargo(link):
122
+ # get the url for downloading source file: https://crates.io/api/v1/crates/<name>/<version>/download
123
+ ret = False
124
+ new_link = ''
125
+ host = 'https://crates.io/api/v1/crates'
126
+
127
+ try:
128
+ dn_loc_re = re.findall(r'crates.io\/crates\/([^\/]+)\/?([^\/]*)', link)
129
+ if dn_loc_re:
130
+ oss_name = dn_loc_re[0][0]
131
+ oss_version = dn_loc_re[0][1]
132
+
133
+ new_link = f'{host}/{oss_name}/{oss_version}/download'
134
+ res = urlopen(new_link)
135
+ if res.getcode() == 200:
136
+ ret = True
137
+ else:
138
+ logger.warning(f'Cannot find the valid link for cargo (url:{new_link}')
139
+ except Exception as error:
140
+ ret = False
141
+ logger.warning(f'Cannot find the link for cargo (url:{link}({(new_link)})): {error}')
142
+
143
+ return ret, new_link
144
+
145
+
146
+ def get_download_location_for_go(link):
147
+ # get the url for downloading source file: https://proxy.golang.org/<module>/@v/VERSION.zip
148
+ ret = False
149
+ new_link = ''
150
+ host = 'https://proxy.golang.org'
151
+
152
+ try:
153
+ dn_loc_re = re.findall(r'pkg.go.dev\/([^\@]+)\@?([^\/]*)', link)
154
+ if dn_loc_re:
155
+ oss_name = dn_loc_re[0][0]
156
+ if oss_name.endswith('/'):
157
+ oss_name = oss_name[:-1]
158
+ oss_version = dn_loc_re[0][1]
159
+
160
+ new_link = f'{host}/{oss_name}/@v/{oss_version}.zip'
161
+ try:
162
+ res = urlopen(new_link)
163
+ if res.getcode() == 200:
164
+ ret = True
165
+ else:
166
+ logger.warning(f'Cannot find the valid link for go (url:{new_link}')
167
+ except Exception as e:
168
+ logger.warning(f'Fail to find the valid link for go (url:{new_link}: {e}')
169
+ except Exception as error:
170
+ ret = False
171
+ logger.warning(f'Cannot find the link for go (url:{link}({(new_link)})): {error}')
172
+
173
+ return ret, new_link
103
174
 
104
175
 
105
176
  def get_download_location_for_pypi(link):
@@ -111,7 +182,7 @@ def get_download_location_for_pypi(link):
111
182
  try:
112
183
  dn_loc_re = re.findall(r'pypi.org\/project\/?([^\/]*)\/?([^\/]*)', link)
113
184
  oss_name = dn_loc_re[0][0]
114
- oss_name = re.sub(r"[-_.]+", "-", oss_name).lower()
185
+ oss_name = re.sub(r"[-_.]+", "-", oss_name)
115
186
  oss_version = dn_loc_re[0][1]
116
187
 
117
188
  new_link = f'{host}/packages/source/{oss_name[0]}/{oss_name}/{oss_name}-{oss_version}.tar.gz'
@@ -121,8 +192,8 @@ def get_download_location_for_pypi(link):
121
192
  ret = True
122
193
  else:
123
194
  logger.warning(f'Cannot find the valid link for pypi (url:{new_link}')
124
- except Exception as e:
125
- oss_name = re.sub(r"[-]+", "_", oss_name).lower()
195
+ except Exception:
196
+ oss_name = re.sub(r"[-]+", "_", oss_name)
126
197
  new_link = f'{host}/packages/source/{oss_name[0]}/{oss_name}/{oss_name}-{oss_version}.tar.gz'
127
198
  res = urlopen(new_link)
128
199
  if res.getcode() == 200:
@@ -35,6 +35,7 @@ SHEET_NAME_FOR_SCANNER = {
35
35
  # pub: https://pub.dev/packages/(package)/versions/(version)
36
36
  # Cocoapods : https://cocoapods.org/(package)
37
37
  # go : https://pkg.go.dev/(package_name_with_slash)@(version)
38
+ # cargo : https://crates.io/crates/(crate_name)/(version)
38
39
  PKG_PATTERN = {
39
40
  "pypi": r'https?:\/\/pypi\.org\/project\/([^\/]+)[\/]?([^\/]*)',
40
41
  "pypi2": r'https?:\/\/files\.pythonhosted\.org\/packages\/source\/[\w]\/([^\/]+)\/[\S]+-([^\-]+)\.tar\.gz',
@@ -43,5 +44,6 @@ PKG_PATTERN = {
43
44
  "npm2": r'https?:\/\/www\.npmjs\.com\/package\/(\@[^\/]+\/[^\/]+)(?:\/v\/)?([^\/]*)',
44
45
  "pub": r'https?:\/\/pub\.dev\/packages\/([^\/]+)(?:\/versions\/)?([^\/]*)',
45
46
  "cocoapods": r'https?:\/\/cocoapods\.org\/pods\/([^\/]+)',
46
- "go": r'https?:\/\/pkg.go.dev\/([^\@]+)\@?v?([^\/]*)'
47
+ "go": r'https?:\/\/pkg.go.dev\/([^\@]+)\@?v?([^\/]*)',
48
+ "cargo": r'https?:\/\/crates\.io\/crates\/([^\/]+)\/?([^\/]*)',
47
49
  }
fosslight_util/correct.py CHANGED
@@ -61,17 +61,15 @@ def correct_with_yaml(correct_filepath, path_to_scan, scan_item):
61
61
 
62
62
  yaml_path_exists = True
63
63
  exclude_fileitems.append(idx)
64
-
65
- if not yaml_path_exists:
64
+ if scanner_name == FOSSLIGHT_SOURCE and not yaml_path_exists:
66
65
  correct_item = copy.deepcopy(yaml_file_item)
67
66
  if os.path.exists(os.path.normpath(yaml_file_item.source_name_or_path)):
68
67
  correct_item.comment = 'Loaded from sbom-info.yaml'
69
68
  correct_fileitems.append(correct_item)
70
69
  else:
71
- if scanner_name == FOSSLIGHT_SOURCE:
72
- correct_item.exclude = True
73
- correct_item.comment = 'Added by sbom-info.yaml'
74
- correct_fileitems.append(correct_item)
70
+ correct_item.exclude = True
71
+ correct_item.comment = 'Added by sbom-info.yaml'
72
+ correct_fileitems.append(correct_item)
75
73
  if correct_fileitems:
76
74
  scan_item.append_file_items(correct_fileitems, scanner_name)
77
75
  find_match = True
@@ -26,6 +26,7 @@ import platform
26
26
  import subprocess
27
27
  import re
28
28
  from typing import Tuple
29
+ import urllib.parse
29
30
 
30
31
  logger = logging.getLogger(constant.LOGGER_NAME)
31
32
  compression_extension = {".tar.bz2", ".tar.gz", ".tar.xz", ".tgz", ".tar", ".zip", ".jar", ".bz2"}
@@ -94,7 +95,8 @@ def parse_src_link(src_link):
94
95
 
95
96
  def cli_download_and_extract(link: str, target_dir: str, log_dir: str, checkout_to: str = "",
96
97
  compressed_only: bool = False, ssh_key: str = "",
97
- id: str = "", git_token: str = "") -> Tuple[bool, str, str, str]:
98
+ id: str = "", git_token: str = "",
99
+ called_cli: bool = True) -> Tuple[bool, str, str, str]:
98
100
  global logger
99
101
 
100
102
  success = True
@@ -123,8 +125,11 @@ def cli_download_and_extract(link: str, target_dir: str, log_dir: str, checkout_
123
125
  is_rubygems = src_info.get("rubygems", False)
124
126
 
125
127
  # General download (git clone, wget)
126
- success_git, msg, oss_name, oss_version = download_git_clone(link, target_dir, checkout_to,
127
- tag, branch, ssh_key, id, git_token)
128
+ success_git, msg, oss_name, oss_version = download_git_clone(link, target_dir,
129
+ checkout_to,
130
+ tag, branch,
131
+ ssh_key, id, git_token,
132
+ called_cli)
128
133
  link = change_ssh_link_to_https(link)
129
134
  if (not is_rubygems) and (not success_git):
130
135
  if os.path.isfile(target_dir):
@@ -202,34 +207,44 @@ def get_github_token(git_url):
202
207
  return github_token
203
208
 
204
209
 
205
- def download_git_repository(refs_to_checkout, git_url, target_dir, tag):
210
+ def download_git_repository(refs_to_checkout, git_url, target_dir, tag, called_cli=True):
206
211
  success = False
207
212
  oss_version = ""
208
- clone_default_branch_flag = False
209
213
 
210
214
  logger.info(f"Download git url :{git_url}")
215
+ env = os.environ.copy()
216
+ if not called_cli:
217
+ env["GIT_TERMINAL_PROMPT"] = "0"
211
218
  if refs_to_checkout:
212
219
  try:
213
220
  # gitPython uses the branch argument the same whether you check out to a branch or a tag.
214
- repo = Repo.clone_from(git_url, target_dir, branch=refs_to_checkout)
215
- success = True
221
+ Repo.clone_from(git_url, target_dir, branch=refs_to_checkout, env=env)
222
+ if any(Path(target_dir).iterdir()):
223
+ success = True
224
+ oss_version = refs_to_checkout
225
+ logger.info(f"Files found in {target_dir} after clone.")
226
+ else:
227
+ logger.info(f"No files found in {target_dir} after clone.")
228
+ success = False
216
229
  except GitCommandError as error:
217
- logger.debug(f"Git checkout error:{error}")
230
+ logger.info(f"Git checkout error:{error}")
231
+ success = False
232
+ except Exception as e:
233
+ logger.info(f"Repo.clone_from error:{e}")
218
234
  success = False
219
235
 
220
236
  if not success:
221
- repo = Repo.clone_from(git_url, target_dir)
222
- clone_default_branch_flag = True
223
- success = True
224
-
225
- if refs_to_checkout != tag or clone_default_branch_flag:
226
- oss_version = repo.active_branch.name
227
- else:
228
- oss_version = repo.git.describe('--tags')
237
+ Repo.clone_from(git_url, target_dir, env=env)
238
+ if any(Path(target_dir).iterdir()):
239
+ success = True
240
+ else:
241
+ logger.info(f"No files found in {target_dir} after clone.")
242
+ success = False
229
243
  return success, oss_version
230
244
 
231
245
 
232
- def download_git_clone(git_url, target_dir, checkout_to="", tag="", branch="", ssh_key="", id="", git_token=""):
246
+ def download_git_clone(git_url, target_dir, checkout_to="", tag="", branch="",
247
+ ssh_key="", id="", git_token="", called_cli=True):
233
248
  oss_name = get_github_ossname(git_url)
234
249
  refs_to_checkout = decide_checkout(checkout_to, tag, branch)
235
250
  msg = ""
@@ -253,17 +268,19 @@ def download_git_clone(git_url, target_dir, checkout_to="", tag="", branch="", s
253
268
  logger.info(f"Download git with ssh_key:{git_url}")
254
269
  git_ssh_cmd = f'ssh -i {ssh_key}'
255
270
  with Git().custom_environment(GIT_SSH_COMMAND=git_ssh_cmd):
256
- success, oss_version = download_git_repository(refs_to_checkout, git_url, target_dir, tag)
271
+ success, oss_version = download_git_repository(refs_to_checkout, git_url, target_dir, tag, called_cli)
257
272
  else:
258
273
  if id and git_token:
259
274
  try:
260
275
  m = re.match(r"^(ht|f)tp(s?)\:\/\/", git_url)
261
276
  protocol = m.group()
262
277
  if protocol:
263
- git_url = git_url.replace(protocol, f"{protocol}{id}:{git_token}@")
278
+ encoded_git_token = urllib.parse.quote(git_token, safe='')
279
+ encoded_id = urllib.parse.quote(id, safe='')
280
+ git_url = git_url.replace(protocol, f"{protocol}{encoded_id}:{encoded_git_token}@")
264
281
  except Exception as error:
265
282
  logger.info(f"Failed to insert id, token to git url:{error}")
266
- success, oss_version = download_git_repository(refs_to_checkout, git_url, target_dir, tag)
283
+ success, oss_version = download_git_repository(refs_to_checkout, git_url, target_dir, tag, called_cli)
267
284
 
268
285
  logger.info(f"git checkout: {oss_version}")
269
286
  refs_to_checkout = oss_version
@@ -297,7 +314,7 @@ def download_wget(link, target_dir, compressed_only):
297
314
 
298
315
  Path(target_dir).mkdir(parents=True, exist_ok=True)
299
316
 
300
- ret, new_link, oss_name, oss_version = get_downloadable_url(link)
317
+ ret, new_link, oss_name, oss_version, pkg_type = get_downloadable_url(link)
301
318
  if ret and new_link:
302
319
  link = new_link
303
320
 
@@ -306,6 +323,9 @@ def download_wget(link, target_dir, compressed_only):
306
323
  if link.endswith(ext):
307
324
  success = True
308
325
  break
326
+ if not success:
327
+ if pkg_type == 'cargo':
328
+ success = True
309
329
  else:
310
330
  success = True
311
331
 
@@ -313,7 +333,11 @@ def download_wget(link, target_dir, compressed_only):
313
333
  raise Exception('Not supported compression type (link:{0})'.format(link))
314
334
 
315
335
  logger.info(f"wget: {link}")
316
- downloaded_file = wget.download(link, target_dir)
336
+ if pkg_type == 'cargo':
337
+ outfile = os.path.join(target_dir, f'{oss_name}.tar.gz')
338
+ downloaded_file = wget.download(link, out=outfile)
339
+ else:
340
+ downloaded_file = wget.download(link, target_dir)
317
341
  if platform.system() != "Windows":
318
342
  signal.alarm(0)
319
343
  else:
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ # Copyright (c) 2025 LG Electronics Inc.
4
+ # SPDX-License-Identifier: Apache-2.0
5
+
6
+ import os
7
+ import fnmatch
8
+ from typing import List
9
+
10
+
11
+ def excluding_files(patterns: List[str], path_to_scan: str) -> List[str]:
12
+ excluded_paths = set()
13
+
14
+ # Normalize patterns: e.g., 'sample/', 'sample/*' -> 'sample'
15
+ # Replace backslash with slash
16
+ normalized_patterns = []
17
+ for pattern in patterns:
18
+ pattern = pattern.replace('\\', '/')
19
+ if pattern.endswith('/') or pattern.endswith('/*'):
20
+ pattern = pattern.rstrip('/*')
21
+ normalized_patterns.append(pattern)
22
+
23
+ # Traverse directories
24
+ for root, dirs, files in os.walk(path_to_scan):
25
+ remove_dir_list = []
26
+
27
+ # (1) Directory matching
28
+ for d in dirs:
29
+ dir_name = d
30
+ dir_path = os.path.relpath(os.path.join(root, d), path_to_scan).replace('\\', '/')
31
+ matched = False
32
+
33
+ for pat in normalized_patterns:
34
+ # Match directory name
35
+ if fnmatch.fnmatch(dir_name, pat):
36
+ matched = True
37
+
38
+ # Match the full relative path
39
+ if not matched:
40
+ if fnmatch.fnmatch(dir_path, pat) or fnmatch.fnmatch(dir_path, pat + "/*"):
41
+ matched = True
42
+
43
+ # If matched, exclude all files under this directory and stop checking patterns
44
+ if matched:
45
+ sub_root_path = os.path.join(root, d)
46
+ for sr, _, sf in os.walk(sub_root_path):
47
+ for sub_file in sf:
48
+ sub_file_path = os.path.relpath(os.path.join(sr, sub_file), path_to_scan)
49
+ excluded_paths.add(sub_file_path.replace('\\', '/'))
50
+ remove_dir_list.append(d)
51
+ break
52
+
53
+ # (1-2) Prune matched directories from further traversal
54
+ for rd in remove_dir_list:
55
+ dirs.remove(rd)
56
+
57
+ # (2) File matching
58
+ for f in files:
59
+ file_path = os.path.relpath(os.path.join(root, f), path_to_scan).replace('\\', '/')
60
+ for pat in normalized_patterns:
61
+ if fnmatch.fnmatch(file_path, pat) or fnmatch.fnmatch(file_path, pat + "/*"):
62
+ excluded_paths.add(file_path)
63
+ break
64
+
65
+ return sorted(excluded_paths)
fosslight_util/help.py CHANGED
@@ -3,7 +3,10 @@
3
3
  # Copyright (c) 2021 LG Electronics Inc.
4
4
  # SPDX-License-Identifier: Apache-2.0
5
5
  import sys
6
- import pkg_resources
6
+ try:
7
+ from importlib.metadata import version, PackageNotFoundError
8
+ except ImportError:
9
+ from importlib_metadata import version, PackageNotFoundError # Python <3.8
7
10
 
8
11
  _HELP_MESSAGE_COMMON = """
9
12
  _______ _______ _______ _______ ___ ___ __
@@ -50,7 +53,10 @@ class PrintHelpMsg():
50
53
  def print_package_version(pkg_name: str, msg: str = "", exitopt: bool = True) -> str:
51
54
  if msg == "":
52
55
  msg = f"{pkg_name} Version:"
53
- cur_version = pkg_resources.get_distribution(pkg_name).version
56
+ try:
57
+ cur_version = version(pkg_name)
58
+ except PackageNotFoundError:
59
+ cur_version = "unknown"
54
60
 
55
61
  if exitopt:
56
62
  print(f'{msg} {cur_version}')
@@ -48,7 +48,8 @@ def check_output_format(output='', format='', customized_format={}):
48
48
  if format:
49
49
  if output_extension != basename_extension:
50
50
  success = False
51
- msg = f"(-o & -f option) Enter the same extension of output file(-o:'{output}') with format(-f:'{format}')."
51
+ msg = f"(-o & -f option) Enter the same extension of output file(-o:'{output}') \
52
+ with format(-f:'{format}')."
52
53
  else:
53
54
  if basename_extension not in support_format.values():
54
55
  success = False
@@ -96,7 +97,8 @@ def check_output_formats(output='', formats=[], customized_format={}):
96
97
  if formats:
97
98
  if basename_extension not in output_extensions:
98
99
  success = False
99
- msg = f"(-o & -f option) The format of output file(-o:'{output}') should be in the format list(-f:'{formats}')."
100
+ msg = f"(-o & -f option) The format of output file(-o:'{output}') \
101
+ should be in the format list(-f:'{formats}')."
100
102
  else:
101
103
  if basename_extension not in support_format.values():
102
104
  success = False
@@ -145,7 +147,8 @@ def check_output_formats_v2(output='', formats=[], customized_format={}):
145
147
  if formats:
146
148
  if basename_extension not in output_extensions:
147
149
  success = False
148
- msg = f"(-o & -f option) The format of output file(-o:'{output}') should be in the format list(-f:'{formats}')."
150
+ msg = f"(-o & -f option) The format of output file(-o:'{output}') \
151
+ should be in the format list(-f:'{formats}')."
149
152
  else:
150
153
  if basename_extension not in support_format.values():
151
154
  success = False
@@ -157,6 +160,7 @@ def check_output_formats_v2(output='', formats=[], customized_format={}):
157
160
  if not output_extensions:
158
161
  output_extensions = ['.xlsx']
159
162
  if not formats:
163
+ formats = []
160
164
  for ext in output_extensions:
161
165
  for key, value in support_format.items():
162
166
  if value == ext:
fosslight_util/set_log.py CHANGED
@@ -6,7 +6,6 @@
6
6
  import logging
7
7
  import os
8
8
  from pathlib import Path
9
- import pkg_resources
10
9
  import sys
11
10
  import platform
12
11
  from . import constant as constant
@@ -15,6 +14,11 @@ import coloredlogs
15
14
  from typing import Tuple
16
15
  from logging import Logger
17
16
 
17
+ try:
18
+ from importlib.metadata import version, PackageNotFoundError
19
+ except ImportError:
20
+ from importlib_metadata import version, PackageNotFoundError # Python <3.8
21
+
18
22
 
19
23
  def init_check_latest_version(pkg_version="", main_package_name=""):
20
24
 
@@ -92,9 +96,11 @@ def init_log(log_file: str, create_file: bool = True, stream_log_level: int = lo
92
96
  if main_package_name != "":
93
97
  pkg_info = main_package_name
94
98
  try:
95
- pkg_version = pkg_resources.get_distribution(main_package_name).version
99
+ pkg_version = version(main_package_name)
96
100
  init_check_latest_version(pkg_version, main_package_name)
97
101
  pkg_info = main_package_name + " v" + pkg_version
102
+ except PackageNotFoundError:
103
+ logger.debug('Cannot check the version: Package not found')
98
104
  except Exception as error:
99
105
  logger.debug('Cannot check the version:' + str(error))
100
106
  _result_log["Tool Info"] = pkg_info
@@ -5,16 +5,11 @@
5
5
  # SPDX-License-Identifier: Apache-2.0
6
6
 
7
7
  import os
8
- import sys
9
8
  import logging
10
9
  import re
11
- import json
12
10
  from pathlib import Path
13
- from datetime import datetime
14
- from fosslight_util.spdx_licenses import get_spdx_licenses_json, get_license_from_nick
15
11
  from fosslight_util.constant import (LOGGER_NAME, FOSSLIGHT_DEPENDENCY, FOSSLIGHT_SCANNER,
16
- FOSSLIGHT_BINARY, FOSSLIGHT_SOURCE)
17
- from fosslight_util.oss_item import CHECKSUM_NULL, get_checksum_sha1
12
+ FOSSLIGHT_SOURCE)
18
13
  import traceback
19
14
 
20
15
  logger = logging.getLogger(LOGGER_NAME)
@@ -27,14 +22,11 @@ try:
27
22
  from cyclonedx.model import XsUri, ExternalReferenceType
28
23
  from cyclonedx.model.bom import Bom
29
24
  from cyclonedx.model.component import Component, ComponentType, HashAlgorithm, HashType, ExternalReference
30
- from cyclonedx.model.contact import OrganizationalEntity
31
25
  from cyclonedx.output import make_outputter, BaseOutput
32
26
  from cyclonedx.output.json import JsonV1Dot6
33
27
  from cyclonedx.schema import OutputFormat, SchemaVersion
34
- from cyclonedx.validation import make_schemabased_validator
35
28
  from cyclonedx.validation.json import JsonStrictValidator
36
29
  from cyclonedx.output.json import Json as JsonOutputter
37
- from cyclonedx.output.xml import Xml as XmlOutputter
38
30
  from cyclonedx.validation.xml import XmlValidator
39
31
  except Exception:
40
32
  logger.info('No import cyclonedx-python-lib')
@@ -66,7 +58,6 @@ def write_cyclonedx(output_file_without_ext, output_extension, scan_item):
66
58
  type=ComponentType.APPLICATION,
67
59
  bom_ref=str(comp_id))
68
60
  relation_tree = {}
69
- bom_ref_packages = []
70
61
 
71
62
  output_dir = os.path.dirname(output_file_without_ext)
72
63
  Path(output_dir).mkdir(parents=True, exist_ok=True)
@@ -82,7 +73,7 @@ def write_cyclonedx(output_file_without_ext, output_extension, scan_item):
82
73
  comp_type = ComponentType.LIBRARY
83
74
 
84
75
  for oss_item in file_item.oss_items:
85
- if oss_item.name == '':
76
+ if oss_item.name == '' or oss_item.name == '-':
86
77
  if scanner_name == FOSSLIGHT_DEPENDENCY:
87
78
  continue
88
79
  else:
@@ -102,7 +93,8 @@ def write_cyclonedx(output_file_without_ext, output_extension, scan_item):
102
93
  if scanner_name == FOSSLIGHT_DEPENDENCY and file_item.purl:
103
94
  comp.purl = PackageURL.from_string(file_item.purl)
104
95
  if scanner_name != FOSSLIGHT_DEPENDENCY:
105
- comp.hashes = [HashType(alg=HashAlgorithm.SHA_1, content=file_item.checksum)]
96
+ if file_item.checksum != '0':
97
+ comp.hashes = [HashType(alg=HashAlgorithm.SHA_1, content=file_item.checksum)]
106
98
 
107
99
  if oss_item.download_location != '':
108
100
  comp.external_references = [ExternalReference(url=XsUri(oss_item.download_location),
@@ -113,7 +105,7 @@ def write_cyclonedx(output_file_without_ext, output_extension, scan_item):
113
105
  try:
114
106
  oss_licenses.append(lc_factory.make_from_string(ol))
115
107
  except Exception:
116
- logger.info(f'No spdx license name: {oi}')
108
+ logger.info(f'No spdx license name: {ol}')
117
109
  if oss_licenses:
118
110
  comp.licenses = oss_licenses
119
111
 
@@ -192,9 +184,9 @@ def write_cyclonedx_json(bom, result_file):
192
184
  except MissingOptionalDependencyException as error:
193
185
  logger.debug(f'JSON-validation was skipped due to {error}')
194
186
  except Exception as e:
187
+ logger.warning(f'Fail to write cyclonedx json: {e}')
195
188
  success = False
196
189
  return success
197
-
198
190
 
199
191
 
200
192
  def write_cyclonedx_xml(bom, result_file):
@@ -213,5 +205,6 @@ def write_cyclonedx_xml(bom, result_file):
213
205
  except MissingOptionalDependencyException as error:
214
206
  logger.debug(f'XML-validation was skipped due to {error}')
215
207
  except Exception as e:
208
+ logger.warning(f'Fail to write cyclonedx xml: {e}')
216
209
  success = False
217
- return success
210
+ return success
@@ -34,6 +34,7 @@ IDX_FILE = 0
34
34
  IDX_EXCLUDE = 7
35
35
  logger = logging.getLogger(LOGGER_NAME)
36
36
  COVER_SHEET_NAME = 'Scanner Info'
37
+ MAX_EXCEL_URL_LENGTH = 255
37
38
 
38
39
 
39
40
  def get_header_row(sheet_name, extended_header={}):
@@ -181,7 +182,10 @@ def write_result_to_sheet(worksheet, sheet_contents):
181
182
  for row_item in sheet_contents:
182
183
  worksheet.write(row, 0, row)
183
184
  for col_num, value in enumerate(row_item):
184
- worksheet.write(row, col_num + 1, str(value))
185
+ if len(value) > MAX_EXCEL_URL_LENGTH and (value.startswith("http://") or value.startswith("https://")):
186
+ worksheet.write_string(row, col_num + 1, str(value))
187
+ else:
188
+ worksheet.write(row, col_num + 1, str(value))
185
189
  row += 1
186
190
 
187
191
 
@@ -6,7 +6,7 @@
6
6
  import logging
7
7
  import os
8
8
  import json
9
- from fosslight_util.constant import LOGGER_NAME
9
+ from fosslight_util.constant import LOGGER_NAME, FOSSLIGHT_DEPENDENCY
10
10
  from fosslight_util.oss_item import ScannerItem
11
11
  from typing import List
12
12
 
@@ -20,22 +20,27 @@ def write_scancodejson(output_dir: str, output_filename: str, oss_list: List[Sca
20
20
  json_output['summary'] = {}
21
21
  json_output['license_detections'] = []
22
22
  json_output['files'] = []
23
+ json_output['dependencies'] = []
23
24
 
24
- for file_items in oss_list.file_items.values():
25
+ for scanner, file_items in oss_list.file_items.items():
25
26
  for fi in file_items:
26
- if fi.exclude:
27
- continue
28
- if fi.oss_items and (all(oss_item.exclude for oss_item in fi.oss_items)):
29
- continue
30
- if not fi.source_name_or_path:
31
- fi.source_name_or_path = EMPTY_FILE_PATH
32
- json_output['files'] = add_item_in_files(fi, json_output['files'])
27
+ if scanner == FOSSLIGHT_DEPENDENCY:
28
+ json_output['dependencies'] = add_item_in_deps(fi, json_output['dependencies'])
29
+ else:
30
+ if fi.exclude:
31
+ continue
32
+ if fi.oss_items and (all(oss_item.exclude for oss_item in fi.oss_items)):
33
+ continue
34
+ if not fi.source_name_or_path:
35
+ fi.source_name_or_path = EMPTY_FILE_PATH
36
+ json_output['files'] = add_item_in_files(fi, json_output['files'])
33
37
 
34
38
  with open(os.path.join(output_dir, output_filename), 'w') as f:
35
39
  json.dump(json_output, f, sort_keys=False, indent=4)
36
40
 
37
41
 
38
- def append_oss_item_in_filesitem(oss_items, files_item):
42
+ def get_oss_item_list(oss_items):
43
+ scan_oss_items = []
39
44
  for oi in oss_items:
40
45
  if oi.exclude:
41
46
  continue
@@ -46,9 +51,9 @@ def append_oss_item_in_filesitem(oss_items, files_item):
46
51
  oss_item['copyright'] = oi.copyright
47
52
  oss_item['download_location'] = oi.download_location
48
53
  oss_item['comment'] = oi.comment
49
- files_item['oss'].append(oss_item)
54
+ scan_oss_items.append(oss_item)
50
55
 
51
- return files_item
56
+ return scan_oss_items
52
57
 
53
58
 
54
59
  def add_item_in_files(file_item, files_list):
@@ -57,8 +62,20 @@ def add_item_in_files(file_item, files_list):
57
62
  files_item['name'] = os.path.basename(file_item.source_name_or_path)
58
63
  files_item['is_binary'] = file_item.is_binary
59
64
  files_item['base_name'], files_item['extension'] = os.path.splitext(os.path.basename(file_item.source_name_or_path))
60
- files_item['oss'] = []
61
- files_item = append_oss_item_in_filesitem(file_item.oss_items, files_item)
65
+ files_item['oss'] = get_oss_item_list(file_item.oss_items)
66
+
62
67
  files_list.append(files_item)
63
68
 
64
69
  return files_list
70
+
71
+
72
+ def add_item_in_deps(file_item, deps_list):
73
+ deps_item = {}
74
+ deps_item['purl'] = file_item.purl
75
+ deps_item['scope'] = 'dependencies'
76
+ deps_item['depends_on'] = file_item.depends_on
77
+ deps_item['oss'] = get_oss_item_list(file_item.oss_items)
78
+
79
+ deps_list.append(deps_item)
80
+
81
+ return deps_list
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fosslight-util
3
- Version: 2.1.7
3
+ Version: 2.1.18
4
4
  Summary: FOSSLight Util
5
5
  Home-page: https://github.com/fosslight/fosslight_util
6
6
  Author: LG Electronics
@@ -0,0 +1,32 @@
1
+ fosslight_util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ fosslight_util/_get_downloadable_url.py,sha256=SqXCESg1GVXhCpObZoceXdFJVecDrDp-7qW88w0QsCY,12091
3
+ fosslight_util/compare_yaml.py,sha256=eLqqCLgERxRHN5vsnpQVMXIEU862Lx66mD_y4uMgQE4,2916
4
+ fosslight_util/constant.py,sha256=zElnWOzXt020sYiFTiRQn8ZjZyZpL3aPmfAqfQLcxJk,2278
5
+ fosslight_util/correct.py,sha256=1WEAL-9_KhjFPLucPhv0PNN3K7avm0z8mU6sTuSyeHM,3864
6
+ fosslight_util/cover.py,sha256=qqqKzxqFwKimal764FaugRUBcHWdeKt8af6xeK0mH8E,2040
7
+ fosslight_util/download.py,sha256=V3EBgXt-xHarJZFrskXHaX4Ij81ZPjj6hzvtmpKu7xE,17642
8
+ fosslight_util/exclude.py,sha256=fDmBsZJ_F7O9Oh2T-07R03XNbElo1tFaf_z01KfSAqU,2399
9
+ fosslight_util/help.py,sha256=Bmyz-eFP0X0qUfgFPrWiuyUPE0TLQfWjgfHTzJBIInc,2377
10
+ fosslight_util/oss_item.py,sha256=8W2HlwqGH3l1iPPdvycrRYKsBSBpqAkqYyYtBVPgMtY,6868
11
+ fosslight_util/output_format.py,sha256=BP23LspxawDZ_a99oWLVKWUQ-G7P5uoUpjEXhkRFKwc,8801
12
+ fosslight_util/parsing_yaml.py,sha256=2zx_N5lMkXT1dRmfJMpzlrru-y_2F_CkVbGlba6vQpU,5380
13
+ fosslight_util/read_excel.py,sha256=-QvrdxaNqYOpIm1H7ZqIEh5NLvFPymZo6BAOZcQmQug,5263
14
+ fosslight_util/set_log.py,sha256=AbcLFLvY9GSOYSN0a110wO5gNcyc8KKnNjl7GxHEW9A,4008
15
+ fosslight_util/spdx_licenses.py,sha256=GvMNe_D4v2meapTVwPu2BJXInnTo3_gIzg669eJhUu0,3691
16
+ fosslight_util/timer_thread.py,sha256=5VbZENQPD-N0NUmzEktqGr6Am-e7vxD79K05mmr29g0,433
17
+ fosslight_util/write_cyclonedx.py,sha256=hq817j-0OM89B8jtZKgHgvVa0YEaYHlz_8R5vNpe21I,9662
18
+ fosslight_util/write_excel.py,sha256=QUIMCnmEKJoSpri5RctBcKLvhDShLdZUP_dhHv-sVy8,10165
19
+ fosslight_util/write_opossum.py,sha256=ltmo6SkugKWdAYupeCqwE4-3lua0GwLpix1XqFC-tT8,11678
20
+ fosslight_util/write_scancodejson.py,sha256=dMCjTtUnNR5BCL6gBCleDT8bTSAN5Gg2RAfimmkGXUE,2692
21
+ fosslight_util/write_spdx.py,sha256=Ov9jBlfVrkWIymcfAxbupUxDZKfCOZZGOPZ4v-x230M,12108
22
+ fosslight_util/write_txt.py,sha256=BEFjYBppqk1CITx-fUN4vfvKv0XCs1GXWtc2Iu-etU4,629
23
+ fosslight_util/write_yaml.py,sha256=QlEKoIPQsEaYERfbP53TeKgnllYzhLQWm5wYjnWtVjE,3238
24
+ fosslight_util/resources/frequentLicenselist.json,sha256=GUhzK6tu7ok10fekOnmVmUgIGRC-acGABZKTNKfDyYA,4776157
25
+ fosslight_util/resources/frequent_license_nick_list.json,sha256=ryU2C_6ZxHbz90_sUN9OvI9GXkCMLu7oGcmd9W79YYo,5005
26
+ fosslight_util/resources/licenses.json,sha256=mK55z-bhY7Mjpj2KsO1crKGGL-X3F6MBFQJ0zLlx010,240843
27
+ fosslight_util-2.1.18.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
28
+ fosslight_util-2.1.18.dist-info/METADATA,sha256=eiYd-q6MOwvzp-SPII-NU2MPNQs6rdm9PgPZEWdweFY,6500
29
+ fosslight_util-2.1.18.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
30
+ fosslight_util-2.1.18.dist-info/entry_points.txt,sha256=bzXX5i7HZ13V8BLKvtu_9KO3ZjtRypH-XszOXT6I3bU,69
31
+ fosslight_util-2.1.18.dist-info/top_level.txt,sha256=2qyYWGLakgBRy4BqoBNt-I5C29tBr_e93e5e1pbuTGA,15
32
+ fosslight_util-2.1.18.dist-info/RECORD,,
@@ -1,31 +0,0 @@
1
- fosslight_util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- fosslight_util/_get_downloadable_url.py,sha256=tZz7UTUuLAbz2muXocOb9epMY_6RXIt-GEM8jhN0c3o,9315
3
- fosslight_util/compare_yaml.py,sha256=eLqqCLgERxRHN5vsnpQVMXIEU862Lx66mD_y4uMgQE4,2916
4
- fosslight_util/constant.py,sha256=Ig3ACm9_QirE4389Wt-IfxOqRkVOUjqGnX1B05z2Byo,2151
5
- fosslight_util/correct.py,sha256=3iUipan8ZX8sbyIIGAPtMkAGvZ4YucjeJwx1K1Bx_z4,3897
6
- fosslight_util/cover.py,sha256=qqqKzxqFwKimal764FaugRUBcHWdeKt8af6xeK0mH8E,2040
7
- fosslight_util/download.py,sha256=bCKvW76XJTnKMAUW5sJZxg_wBUhiybXovJuL04W4P4c,16364
8
- fosslight_util/help.py,sha256=M3_XahUkP794US9Q0NS6ujmGvrFFnKBHsTU95Fg1KpA,2181
9
- fosslight_util/oss_item.py,sha256=8W2HlwqGH3l1iPPdvycrRYKsBSBpqAkqYyYtBVPgMtY,6868
10
- fosslight_util/output_format.py,sha256=AdQVzCpar6n3PCDtijLWbJyFAGKQVE7JhLXlHPtITH4,8678
11
- fosslight_util/parsing_yaml.py,sha256=2zx_N5lMkXT1dRmfJMpzlrru-y_2F_CkVbGlba6vQpU,5380
12
- fosslight_util/read_excel.py,sha256=-QvrdxaNqYOpIm1H7ZqIEh5NLvFPymZo6BAOZcQmQug,5263
13
- fosslight_util/set_log.py,sha256=Xpa94AiOyGEK8ucaYkvkAllvlen1Pq_d6UG6kPYBYBc,3780
14
- fosslight_util/spdx_licenses.py,sha256=GvMNe_D4v2meapTVwPu2BJXInnTo3_gIzg669eJhUu0,3691
15
- fosslight_util/timer_thread.py,sha256=5VbZENQPD-N0NUmzEktqGr6Am-e7vxD79K05mmr29g0,433
16
- fosslight_util/write_cyclonedx.py,sha256=N6r32zj_ikoGkZa9xoreKqdsncoOfFKnV7lHpeiiEhI,9902
17
- fosslight_util/write_excel.py,sha256=G0fIslbWoOtWZCJxbBGLCpUKbhmwrrqhI5PHwRw8_44,9931
18
- fosslight_util/write_opossum.py,sha256=ltmo6SkugKWdAYupeCqwE4-3lua0GwLpix1XqFC-tT8,11678
19
- fosslight_util/write_scancodejson.py,sha256=81n7cWNYoyIKE_V4Kx5YtL2CgjMPIjoKdnSU3inkpJY,2163
20
- fosslight_util/write_spdx.py,sha256=Ov9jBlfVrkWIymcfAxbupUxDZKfCOZZGOPZ4v-x230M,12108
21
- fosslight_util/write_txt.py,sha256=BEFjYBppqk1CITx-fUN4vfvKv0XCs1GXWtc2Iu-etU4,629
22
- fosslight_util/write_yaml.py,sha256=QlEKoIPQsEaYERfbP53TeKgnllYzhLQWm5wYjnWtVjE,3238
23
- fosslight_util/resources/frequentLicenselist.json,sha256=GUhzK6tu7ok10fekOnmVmUgIGRC-acGABZKTNKfDyYA,4776157
24
- fosslight_util/resources/frequent_license_nick_list.json,sha256=ryU2C_6ZxHbz90_sUN9OvI9GXkCMLu7oGcmd9W79YYo,5005
25
- fosslight_util/resources/licenses.json,sha256=mK55z-bhY7Mjpj2KsO1crKGGL-X3F6MBFQJ0zLlx010,240843
26
- fosslight_util-2.1.7.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
27
- fosslight_util-2.1.7.dist-info/METADATA,sha256=_SbQsVJDKbUmd3C0i1fs7C-B9z92g_SLHWrQVb2mi_s,6499
28
- fosslight_util-2.1.7.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
29
- fosslight_util-2.1.7.dist-info/entry_points.txt,sha256=bzXX5i7HZ13V8BLKvtu_9KO3ZjtRypH-XszOXT6I3bU,69
30
- fosslight_util-2.1.7.dist-info/top_level.txt,sha256=2qyYWGLakgBRy4BqoBNt-I5C29tBr_e93e5e1pbuTGA,15
31
- fosslight_util-2.1.7.dist-info/RECORD,,