|
| 1 | +#!/usr/bin/env python |
| 2 | +# -*- coding: utf-8 -*- |
| 3 | +# Copyright (c) 2020 LG Electronics Inc. |
| 4 | +# SPDX-License-Identifier: Apache-2.0 |
| 5 | + |
| 6 | +import sys |
| 7 | +import os |
| 8 | +import multiprocessing |
| 9 | +import warnings |
| 10 | +import platform |
| 11 | +import getopt |
| 12 | +import logging |
| 13 | +import yaml |
| 14 | +from scancode import cli |
| 15 | +from datetime import datetime |
| 16 | +import fosslight_util.constant as constant |
| 17 | +from fosslight_util.set_log import init_log |
| 18 | +from fosslight_util.timer_thread import TimerThread |
| 19 | +from ._parsing_scancode_file_item import parsing_file_item |
| 20 | +from ._parsing_scancode_file_item import get_error_from_header |
| 21 | +from fosslight_util.write_excel import write_excel_and_csv |
| 22 | +from ._help import print_help_msg_source |
| 23 | +from ._license_matched import get_license_list_to_print |
| 24 | + |
| 25 | +logger = logging.getLogger(constant.LOGGER_NAME) |
| 26 | +warnings.filterwarnings("ignore", category=FutureWarning) |
| 27 | +_PKG_NAME = "fosslight_source" |
| 28 | + |
| 29 | + |
| 30 | +def main(): |
| 31 | + argv = sys.argv[1:] |
| 32 | + path_to_scan = "" |
| 33 | + write_json_file = False |
| 34 | + output_file = "" |
| 35 | + print_matched_text = False |
| 36 | + |
| 37 | + try: |
| 38 | + opts, args = getopt.getopt(argv, 'hmjp:o:') |
| 39 | + for opt, arg in opts: |
| 40 | + if opt == "-h": |
| 41 | + print_help_msg_source() |
| 42 | + elif opt == "-p": |
| 43 | + path_to_scan = arg |
| 44 | + elif opt == "-j": |
| 45 | + write_json_file = True |
| 46 | + elif opt == "-o": |
| 47 | + output_file = arg |
| 48 | + elif opt == "-m": |
| 49 | + print_matched_text = True |
| 50 | + except Exception: |
| 51 | + print_help_msg_source() |
| 52 | + |
| 53 | + timer = TimerThread() |
| 54 | + timer.setDaemon(True) |
| 55 | + timer.start() |
| 56 | + run_scan(path_to_scan, output_file, write_json_file, -1, False, print_matched_text) |
| 57 | + |
| 58 | + |
| 59 | +def run_scan(path_to_scan, output_file_name="", |
| 60 | + _write_json_file=False, num_cores=-1, return_results=False, need_license=False): |
| 61 | + global logger |
| 62 | + |
| 63 | + success = True |
| 64 | + msg = "" |
| 65 | + _str_final_result_log = "" |
| 66 | + _result_log = {} |
| 67 | + result_list = [] |
| 68 | + |
| 69 | + _windows = platform.system() == "Windows" |
| 70 | + start_time = datetime.now().strftime('%Y%m%d_%H%M%S') |
| 71 | + |
| 72 | + if output_file_name == "": |
| 73 | + output_file = "FOSSLight-Report_" + start_time |
| 74 | + output_json_file = "scancode_" + start_time |
| 75 | + output_dir = os.getcwd() |
| 76 | + else: |
| 77 | + output_file = output_file_name |
| 78 | + output_json_file = output_file_name |
| 79 | + output_dir = os.path.dirname(os.path.abspath(output_file_name)) |
| 80 | + |
| 81 | + logger, _result_log = init_log(os.path.join(output_dir, "fosslight_src_log_"+start_time+".txt"), |
| 82 | + True, logging.INFO, logging.DEBUG, _PKG_NAME, path_to_scan) |
| 83 | + |
| 84 | + if path_to_scan == "": |
| 85 | + if _windows: |
| 86 | + path_to_scan = os.getcwd() |
| 87 | + else: |
| 88 | + print_help_msg_source() |
| 89 | + |
| 90 | + num_cores = multiprocessing.cpu_count() - 1 if num_cores < 0 else num_cores |
| 91 | + |
| 92 | + if os.path.isdir(path_to_scan): |
| 93 | + try: |
| 94 | + output_json_file = output_json_file+".json" if _write_json_file\ |
| 95 | + else "" |
| 96 | + |
| 97 | + rc, results = cli.run_scan(path_to_scan, max_depth=100, |
| 98 | + strip_root=True, license=True, |
| 99 | + copyright=True, return_results=True, |
| 100 | + processes=num_cores, |
| 101 | + output_json_pp=output_json_file, |
| 102 | + only_findings=True, license_text=True) |
| 103 | + |
| 104 | + if not rc: |
| 105 | + msg = "Source code analysis failed." |
| 106 | + success = False |
| 107 | + |
| 108 | + if results: |
| 109 | + sheet_list = {} |
| 110 | + has_error = False |
| 111 | + if "headers" in results: |
| 112 | + has_error, error_msg = get_error_from_header(results["headers"]) |
| 113 | + if has_error: |
| 114 | + _result_log["Error_files"] = error_msg |
| 115 | + msg = "Failed to analyze :" + error_msg |
| 116 | + if "files" in results: |
| 117 | + rc, result_list, parsing_msg, license_list = parsing_file_item(results["files"], has_error, need_license) |
| 118 | + _result_log["Parsing Log"] = parsing_msg |
| 119 | + if rc: |
| 120 | + if not success: |
| 121 | + success = True |
| 122 | + result_list = sorted( |
| 123 | + result_list, key=lambda row: (''.join(row.licenses))) |
| 124 | + sheet_list["SRC"] = [scan_item.get_row_to_print() for scan_item in result_list] |
| 125 | + if need_license: |
| 126 | + sheet_list["matched_text"] = get_license_list_to_print(license_list) |
| 127 | + |
| 128 | + success_to_write, writing_msg = write_excel_and_csv( |
| 129 | + output_file, sheet_list) |
| 130 | + logger.info("Writing excel :" + str(success_to_write) + " " + writing_msg) |
| 131 | + if success_to_write: |
| 132 | + _result_log["FOSSLight Report"] = output_file + ".xlsx" |
| 133 | + except Exception as ex: |
| 134 | + success = False |
| 135 | + msg = str(ex) |
| 136 | + logger.error("Analyze " + path_to_scan + ":" + msg) |
| 137 | + else: |
| 138 | + success = False |
| 139 | + msg = "Check the path to scan. :" + path_to_scan |
| 140 | + |
| 141 | + if not return_results: |
| 142 | + result_list = [] |
| 143 | + |
| 144 | + scan_result_msg = str(success) if msg == "" else str(success) + "," + msg |
| 145 | + _result_log["Scan Result"] = scan_result_msg |
| 146 | + _result_log["Output Directory"] = output_dir |
| 147 | + try: |
| 148 | + _str_final_result_log = yaml.safe_dump(_result_log, allow_unicode=True, sort_keys=True) |
| 149 | + logger.info(_str_final_result_log) |
| 150 | + except Exception as ex: |
| 151 | + logger.warning("Failed to print result log. " + str(ex)) |
| 152 | + return success, _result_log["Scan Result"], result_list |
| 153 | + |
| 154 | + |
| 155 | +if __name__ == '__main__': |
| 156 | + main() |
0 commit comments