fosslight-util 1.4.48__py3-none-any.whl → 2.0.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.
@@ -6,6 +6,7 @@ import os
6
6
  from fosslight_util.write_excel import write_result_to_excel, write_result_to_csv
7
7
  from fosslight_util.write_opossum import write_opossum
8
8
  from fosslight_util.write_yaml import write_yaml
9
+ from typing import Tuple
9
10
 
10
11
  SUPPORT_FORMAT = {'excel': '.xlsx', 'csv': '.csv', 'opossum': '.json', 'yaml': '.yaml'}
11
12
 
@@ -105,7 +106,8 @@ def check_output_formats(output='', formats=[], customized_format={}):
105
106
  return success, msg, output_path, output_files, output_extensions
106
107
 
107
108
 
108
- def write_output_file(output_file_without_ext, file_extension, sheet_list, extended_header={}, hide_header={}, cover=""):
109
+ def write_output_file(output_file_without_ext: str, file_extension: str, scan_item, extended_header: dict = {},
110
+ hide_header: dict = {}) -> Tuple[bool, str, str]:
109
111
  success = True
110
112
  msg = ''
111
113
 
@@ -114,13 +116,13 @@ def write_output_file(output_file_without_ext, file_extension, sheet_list, exten
114
116
  result_file = output_file_without_ext + file_extension
115
117
 
116
118
  if file_extension == '.xlsx':
117
- success, msg = write_result_to_excel(result_file, sheet_list, extended_header, hide_header, cover)
119
+ success, msg = write_result_to_excel(result_file, scan_item, extended_header, hide_header)
118
120
  elif file_extension == '.csv':
119
- success, msg, result_file = write_result_to_csv(result_file, sheet_list, False, extended_header)
121
+ success, msg, result_file = write_result_to_csv(result_file, scan_item, False, extended_header)
120
122
  elif file_extension == '.json':
121
- success, msg = write_opossum(result_file, sheet_list)
123
+ success, msg = write_opossum(result_file, scan_item)
122
124
  elif file_extension == '.yaml':
123
- success, msg, result_file = write_yaml(result_file, sheet_list, False)
125
+ success, msg, result_file = write_yaml(result_file, scan_item, False)
124
126
  else:
125
127
  success = False
126
128
  msg = f'Not supported file extension({file_extension})'
@@ -8,8 +8,8 @@ import codecs
8
8
  import os
9
9
  import re
10
10
  import sys
11
- from .constant import LOGGER_NAME
12
- from .oss_item import OssItem
11
+ from fosslight_util.constant import LOGGER_NAME
12
+ from fosslight_util.oss_item import OssItem, FileItem
13
13
 
14
14
  _logger = logging.getLogger(LOGGER_NAME)
15
15
  SUPPORT_OSS_INFO_FILES = [r"oss-pkg-info[\s\S]*.ya?ml", r"sbom(-|_)info[\s\S]*.ya?ml"]
@@ -17,7 +17,7 @@ EXAMPLE_OSS_PKG_INFO_LINK = "https://github.com/fosslight/fosslight_prechecker/b
17
17
 
18
18
 
19
19
  def parsing_yml(yaml_file, base_path, print_log=True):
20
- oss_list = []
20
+ fileitems = []
21
21
  license_list = []
22
22
  idx = 1
23
23
  err_reason = ""
@@ -38,37 +38,65 @@ def parsing_yml(yaml_file, base_path, print_log=True):
38
38
  err_reason = "empty"
39
39
  if print_log:
40
40
  _logger.warning(f"The yaml file is empty file: {yaml_file}")
41
- return oss_list, license_list, err_reason
41
+ return fileitems, license_list, err_reason
42
42
 
43
43
  is_old_format = any(x in doc for x in OLD_YAML_ROOT_ELEMENT)
44
44
 
45
+ filepath_list = []
45
46
  for root_element in doc:
46
47
  oss_items = doc[root_element]
47
48
  if oss_items:
48
49
  if not isinstance(oss_items, list) or 'version' not in oss_items[0]:
49
50
  raise AttributeError(f"- Ref. {EXAMPLE_OSS_PKG_INFO_LINK}")
50
51
  for oss in oss_items:
51
- item = OssItem(relative_path)
52
- if not is_old_format:
53
- item.name = root_element
54
- for key, value in oss.items():
55
- if key:
56
- key = key.lower().strip()
57
- set_value_switch(item, key, value, yaml_file)
58
- oss_list.append(item)
59
- license_list.extend(item.license)
60
- idx += 1
52
+ source_paths = get_source_name_or_path_in_yaml(oss)
53
+ for source_path in source_paths:
54
+ if os.path.join(relative_path, source_path) not in filepath_list:
55
+ filepath_list.append(os.path.join(relative_path, source_path))
56
+ fileitem = FileItem(relative_path)
57
+ fileitem.source_name_or_path = source_path
58
+ fileitems.append(fileitem)
59
+ else:
60
+ fileitem = next((i for i in fileitems if i.source_name_or_path == source_path), None)
61
+ ossitem = OssItem()
62
+ if not is_old_format:
63
+ ossitem.name = root_element
64
+ for key, value in oss.items():
65
+ if key:
66
+ key = key.lower().strip()
67
+ set_value_switch(ossitem, key, value, yaml_file)
68
+ fileitem.oss_items.append(ossitem)
69
+ license_list.extend(ossitem.license)
70
+ idx += 1
61
71
  except AttributeError as ex:
62
72
  if print_log:
63
73
  _logger.warning(f"Not supported yaml file format: {yaml_file} {ex}")
64
- oss_list = []
74
+ fileitems = []
65
75
  err_reason = "not_supported"
66
76
  except yaml.YAMLError:
67
77
  if print_log:
68
78
  _logger.warning(f"Error to parse yaml - skip to parse yaml file: {yaml_file}")
69
- oss_list = []
79
+ fileitems = []
70
80
  err_reason = "yaml_error"
71
- return oss_list, set(license_list), err_reason
81
+
82
+ return fileitems, set(license_list), err_reason
83
+
84
+
85
+ def get_source_name_or_path_in_yaml(oss):
86
+ source_name_or_path = []
87
+ find = False
88
+ for key in oss.keys():
89
+ if key in ['file name or path', 'source name or path', 'source path',
90
+ 'file', 'binary name', 'binary path']:
91
+ if isinstance(oss[key], list):
92
+ source_name_or_path = oss[key]
93
+ else:
94
+ source_name_or_path.append(oss[key])
95
+ find = True
96
+ break
97
+ if not find:
98
+ source_name_or_path.append('')
99
+ return source_name_or_path
72
100
 
73
101
 
74
102
  def find_sbom_yaml_files(path_to_find):
@@ -101,9 +129,6 @@ def set_value_switch(oss, key, value, yaml_file=""):
101
129
  oss.download_location = value
102
130
  elif key in ['license', 'license text']:
103
131
  oss.license = value
104
- elif key in ['file name or path', 'source name or path', 'source path',
105
- 'file', 'binary name', 'binary path']:
106
- oss.source_name_or_path = value
107
132
  elif key in ['copyright text', 'copyright']:
108
133
  oss.copyright = value
109
134
  elif key == 'exclude':
@@ -112,16 +137,6 @@ def set_value_switch(oss, key, value, yaml_file=""):
112
137
  oss.comment = value
113
138
  elif key == 'homepage':
114
139
  oss.homepage = value
115
- elif key == 'yocto_package':
116
- oss.yocto_package = value
117
- elif key == 'yocto_recipe':
118
- oss.yocto_recipe = value
119
- elif key == 'vulnerability link':
120
- oss.bin_vulnerability = value
121
- elif key == 'tlsh':
122
- oss.bin_tlsh = value
123
- elif key == 'sha1':
124
- oss.bin_sha1 = value
125
140
  else:
126
141
  if yaml_file != "":
127
142
  _logger.debug(f"file:{yaml_file} - key:{key} cannot be parsed")
@@ -4,27 +4,24 @@
4
4
  # SPDX-License-Identifier: Apache-2.0
5
5
  import logging
6
6
  from typing import List, Dict, Any
7
- import xlrd
7
+ import pandas as pd
8
8
  import json
9
9
  from fosslight_util.constant import LOGGER_NAME
10
- from fosslight_util.oss_item import OssItem
10
+ from fosslight_util.oss_item import OssItem, FileItem
11
11
  from fosslight_util.parsing_yaml import set_value_switch
12
12
 
13
13
  logger = logging.getLogger(LOGGER_NAME)
14
14
  IDX_CANNOT_FOUND = -1
15
15
  PREFIX_BIN = "bin"
16
16
  SHEET_PREFIX_TO_READ = ["bin", "bom", "src"]
17
- xlrd.xlsx.ensure_elementtree_imported(False, None)
18
- xlrd.xlsx.Element_has_iter = True
19
17
 
20
18
 
21
- def read_oss_report(excel_file: str, sheet_names: str = "") -> List[OssItem]:
22
- oss_report_items: List[OssItem] = []
19
+ def read_oss_report(excel_file: str, sheet_names: str = "", basepath: str = "") -> List[FileItem]:
20
+ fileitems: List[FileItem] = []
23
21
  xl_sheets: Dict[str, Any] = {}
24
22
  all_sheet_to_read: List[str] = []
25
23
  not_matched_sheet: List[str] = []
26
24
  any_sheet_matched = False
27
-
28
25
  if sheet_names:
29
26
  sheet_name_prefix_match = False
30
27
  sheet_name_to_read = sheet_names.split(",")
@@ -34,9 +31,8 @@ def read_oss_report(excel_file: str, sheet_names: str = "") -> List[OssItem]:
34
31
 
35
32
  try:
36
33
  logger.info(f"Read data from : {excel_file}")
37
- xl_workbook = xlrd.open_workbook(excel_file)
38
- all_sheet_in_excel = xl_workbook.sheet_names()
39
-
34
+ xl_workbook = pd.ExcelFile(excel_file, engine='openpyxl')
35
+ all_sheet_in_excel = xl_workbook.sheet_names
40
36
  for sheet_to_read in sheet_name_to_read:
41
37
  try:
42
38
  any_sheet_matched = False
@@ -46,10 +42,9 @@ def read_oss_report(excel_file: str, sheet_names: str = "") -> List[OssItem]:
46
42
  sheet_name_lower = sheet_name.lower()
47
43
  if (sheet_name_prefix_match and sheet_name_lower.startswith(sheet_to_read_lower)) \
48
44
  or sheet_to_read_lower == sheet_name_lower:
49
- sheet = xl_workbook.sheet_by_name(sheet_name)
50
- if sheet:
51
- xl_sheets[sheet_name] = sheet
52
- any_sheet_matched = True
45
+ sheet = pd.read_excel(excel_file, sheet_name=sheet_name, engine='openpyxl', na_values='')
46
+ xl_sheets[sheet_name] = sheet.fillna('')
47
+ any_sheet_matched = True
53
48
  if not any_sheet_matched:
54
49
  not_matched_sheet.append(sheet_to_read)
55
50
  except Exception as error:
@@ -62,6 +57,7 @@ def read_oss_report(excel_file: str, sheet_names: str = "") -> List[OssItem]:
62
57
  elif (not sheet_name_prefix_match) and not_matched_sheet:
63
58
  logger.warning(f"Not matched sheet name: {not_matched_sheet}")
64
59
 
60
+ filepath_list = []
65
61
  for sheet_name, xl_sheet in xl_sheets.items():
66
62
  _item_idx = {
67
63
  "ID": IDX_CANNOT_FOUND,
@@ -82,46 +78,44 @@ def read_oss_report(excel_file: str, sheet_names: str = "") -> List[OssItem]:
82
78
  "TLSH": IDX_CANNOT_FOUND,
83
79
  "SHA1": IDX_CANNOT_FOUND
84
80
  }
85
- num_cols = xl_sheet.ncols
86
- num_rows = xl_sheet.nrows
87
- MAX_FIND_HEADER_COLUMN = 5 if num_rows > 5 else num_rows
88
- DATA_START_ROW_IDX = 1
89
- for row_idx in range(0, MAX_FIND_HEADER_COLUMN):
90
- for col_idx in range(row_idx, num_cols):
91
- cell_obj = xl_sheet.cell(row_idx, col_idx)
92
- if cell_obj.value in _item_idx:
93
- _item_idx[cell_obj.value] = col_idx
94
81
 
95
- if len([key for key, value in _item_idx.items() if value != IDX_CANNOT_FOUND]) > 3:
96
- DATA_START_ROW_IDX = row_idx + 1
97
- break
82
+ for index, value in enumerate(xl_sheet.columns.tolist()):
83
+ _item_idx[value] = index
98
84
 
99
85
  # Get all values, iterating through rows and columns
100
86
  column_keys = json.loads(json.dumps(_item_idx))
101
87
 
102
88
  is_bin = True if sheet_name.lower().startswith(PREFIX_BIN) else False
103
89
 
104
- for row_idx in range(DATA_START_ROW_IDX, xl_sheet.nrows):
105
- item = OssItem("")
106
- item.is_binary = is_bin
90
+ for row_idx, row in xl_sheet.iterrows():
107
91
  valid_row = True
108
92
  load_data_cnt = 0
109
-
93
+ source_path = row[1]
94
+ if source_path not in filepath_list:
95
+ filepath_list.append(source_path)
96
+ fileitem = FileItem(basepath)
97
+ fileitem.source_name_or_path = source_path
98
+ fileitems.append(fileitem)
99
+ else:
100
+ fileitem = next((i for i in fileitems if i.source_name_or_path == source_path), None)
101
+ fileitem.is_binary = is_bin
102
+ ossitem = OssItem()
110
103
  for column_key, column_idx in column_keys.items():
111
104
  if column_idx != IDX_CANNOT_FOUND:
112
- cell_obj = xl_sheet.cell(row_idx, column_idx)
113
- cell_value = cell_obj.value
105
+ cell_obj = xl_sheet.iloc[row_idx, column_idx]
106
+ cell_value = cell_obj
107
+
114
108
  if cell_value != "":
115
109
  if column_key != "ID":
116
110
  if column_key:
117
111
  column_key = column_key.lower().strip()
118
- set_value_switch(item, column_key, cell_value)
112
+ set_value_switch(ossitem, column_key, cell_value)
119
113
  load_data_cnt += 1
120
114
  else:
121
115
  valid_row = False if cell_value == "-" else True
122
116
  if valid_row and load_data_cnt > 0:
123
- oss_report_items.append(item)
117
+ fileitem.oss_items.append(ossitem)
124
118
 
125
119
  except Exception as error:
126
120
  logger.error(f"Parsing a OSS Report: {error}")
127
- return oss_report_items
121
+ return fileitems
fosslight_util/set_log.py CHANGED
@@ -12,6 +12,8 @@ import platform
12
12
  from . import constant as constant
13
13
  from lastversion import lastversion
14
14
  import coloredlogs
15
+ from typing import Tuple
16
+ from logging import Logger
15
17
 
16
18
 
17
19
  def init_check_latest_version(pkg_version="", main_package_name=""):
@@ -32,6 +34,21 @@ def init_check_latest_version(pkg_version="", main_package_name=""):
32
34
  logger.debug('Cannot check the latest version:' + str(error))
33
35
 
34
36
 
37
+ def get_os_version():
38
+
39
+ logger = logging.getLogger(constant.LOGGER_NAME)
40
+
41
+ os_version = platform.system() + " " + platform.release()
42
+ if os_version == "Windows 10":
43
+ try:
44
+ windows_build = sys.getwindowsversion().build
45
+ if windows_build >= 22000:
46
+ os_version = "Windows 11"
47
+ except Exception as error:
48
+ logger.debug(str(error))
49
+ return os_version
50
+
51
+
35
52
  class CustomAdapter(logging.LoggerAdapter):
36
53
  def __init__(self, logger, extra):
37
54
  super(CustomAdapter, self).__init__(logger, {})
@@ -41,8 +58,8 @@ class CustomAdapter(logging.LoggerAdapter):
41
58
  return '[%s] %s' % (self.extra, msg), kwargs
42
59
 
43
60
 
44
- def init_log(log_file, create_file=True, stream_log_level=logging.INFO,
45
- file_log_level=logging.DEBUG, main_package_name="", path_to_analyze="", path_to_exclude=[]):
61
+ def init_log(log_file: str, create_file: bool = True, stream_log_level: int = logging.INFO, file_log_level: int = logging.DEBUG,
62
+ main_package_name: str = "", path_to_analyze: str = "", path_to_exclude: list = []) -> Tuple[Logger, dict]:
46
63
 
47
64
  logger = logging.getLogger(constant.LOGGER_NAME)
48
65
 
@@ -70,7 +87,7 @@ def init_log(log_file, create_file=True, stream_log_level=logging.INFO,
70
87
  _result_log = {
71
88
  "Tool Info": main_package_name,
72
89
  "Python version": _PYTHON_VERSION,
73
- "OS": platform.system()+" "+platform.release(),
90
+ "OS": get_os_version(),
74
91
  }
75
92
  if main_package_name != "":
76
93
  pkg_info = main_package_name
@@ -8,6 +8,7 @@ import os
8
8
  import sys
9
9
  import json
10
10
  import traceback
11
+ from typing import Tuple
11
12
 
12
13
  _resources_dir = 'resources'
13
14
  _licenses_json_file = 'licenses.json'
@@ -34,7 +35,7 @@ def get_license_from_nick():
34
35
  return licenses
35
36
 
36
37
 
37
- def get_spdx_licenses_json():
38
+ def get_spdx_licenses_json() -> Tuple[bool, str, str]:
38
39
  success = True
39
40
  error_msg = ''
40
41
  licenses = ''