diff --git a/src/fosslight_scanner/_help.py b/src/fosslight_scanner/_help.py index 04cd265..4a8cb60 100644 --- a/src/fosslight_scanner/_help.py +++ b/src/fosslight_scanner/_help.py @@ -18,15 +18,16 @@ binary\t\t Run FOSSLight Binary prechecker\t\t Run FOSSLight Prechecker all\t\t\t Run all scanners - compare\t\t Compare two FOSSLight reports in yaml format + compare\t\t Compare two FOSSLight reports Options: -h\t\t\t Print help message -p \t\t Path to analyze (ex, -p {input_path}) - * Compare mode: Two FOSSLight reports in yaml format (ex, -p {before.yaml} {after.yaml}) + * Compare mode input file: Two FOSSLight reports (supports excel, yaml) + (ex, -p {before_name}.xlsx {after_name}.xlsx) -w \t\t Link to be analyzed can be downloaded by wget or git clone -f \t\t FOSSLight Report file format (excel, yaml) - * Compare mode: supports excel, json, yaml, html + * Compare mode result file: supports excel, json, yaml, html -o \t\t Output directory or file -c \t\t Number of processes to analyze source -r\t\t\t Keep raw data diff --git a/src/fosslight_scanner/_run_compare.py b/src/fosslight_scanner/_run_compare.py index 19c6418..206b773 100644 --- a/src/fosslight_scanner/_run_compare.py +++ b/src/fosslight_scanner/_run_compare.py @@ -14,6 +14,7 @@ from bs4 import BeautifulSoup import fosslight_util.constant as constant from fosslight_util.compare_yaml import compare_yaml +from fosslight_util.convert_excel_to_yaml import convert_excel_to_yaml logger = logging.getLogger(constant.LOGGER_NAME) ADD = "add" @@ -21,14 +22,19 @@ CHANGE = "change" COMP_STATUS = [ADD, DELETE, CHANGE] +JSON_EXT = '.json' +YAML_EXT = '.yaml' +HTML_EXT = '.html' +XLSX_EXT = '.xlsx' + def write_result_json_yaml(output_file, compared_result, file_ext): ret = True try: with open(output_file, 'w') as f: - if file_ext == '.json': + if file_ext == JSON_EXT: json.dump(compared_result, f, indent=4, sort_keys=True) - elif file_ext == '.yaml': + elif file_ext == YAML_EXT: yaml.dump(compared_result, f, sort_keys=True) except Exception: ret = False @@ -65,7 +71,7 @@ def parse_result_for_table(oi, status): def get_sample_html(): RESOURCES_DIR = 'resources' - SAMPLE_HTML = 'bom_compare.html' + SAMPLE_HTML = f'bom_compare{HTML_EXT}' html_file = os.path.join(RESOURCES_DIR, SAMPLE_HTML) html_f = '' @@ -83,14 +89,14 @@ def get_sample_html(): return html_f -def write_result_html(output_file, compared_result, before_yaml, after_yaml): +def write_result_html(output_file, compared_result, before_f, after_f): ret = True html_f = get_sample_html() if html_f != '': try: f = BeautifulSoup(html_f.read(), 'html.parser') - f.find("li", {"class": "before_f"}).append(before_yaml) - f.find("li", {"class": "after_f"}).append(after_yaml) + f.find("li", {"class": "before_f"}).append(before_f) + f.find("li", {"class": "after_f"}).append(after_f) table_html = f.find("table", {"id": "comp_result"}) @@ -170,22 +176,22 @@ def write_result_xlsx(output_file, compared_result): return ret -def write_compared_result(output_file, compared_result, file_ext, before_yaml='', after_yaml=''): +def write_compared_result(output_file, compared_result, file_ext, before_f='', after_f=''): success = False - if file_ext == "" or file_ext == ".xlsx": + if file_ext == "" or file_ext == XLSX_EXT: success = write_result_xlsx(output_file, compared_result) - elif file_ext == ".html": - output_xlsx_file = os.path.splitext(output_file)[0] + ".xlsx" + elif file_ext == HTML_EXT: + output_xlsx_file = f'{os.path.splitext(output_file)[0]}{XLSX_EXT}' success_xlsx = write_result_xlsx(output_xlsx_file, compared_result) - success = write_result_html(output_file, compared_result, before_yaml, after_yaml) + success = write_result_html(output_file, compared_result, before_f, after_f) if not success_xlsx: logger.error("Fail to write comparison excel file.") else: logger.info(f"In html format, {output_xlsx_file} is generated by default.") output_file = f"{output_xlsx_file}, {output_file}" - elif file_ext == ".json": + elif file_ext == JSON_EXT: success = write_result_json_yaml(output_file, compared_result, file_ext) - elif file_ext == ".yaml": + elif file_ext == YAML_EXT: success = write_result_json_yaml(output_file, compared_result, file_ext) else: logger.info("Not supported file extension") @@ -198,14 +204,14 @@ def get_comparison_result_filename(output_path, output_file, output_extension, _ if output_file != "": result_file = f"{output_file}{output_extension}" else: - if output_extension == '.xlsx' or output_extension == "": - result_file = f"FOSSLight_Compare_{_start_time}.xlsx" - elif output_extension == '.html': - result_file = f"FOSSLight_Compare_{_start_time}.html" - elif output_extension == '.yaml': - result_file = f"FOSSLight_Compare_{_start_time}.yaml" - elif output_extension == '.json': - result_file = f"FOSSLight_Compare_{_start_time}.json" + if output_extension == XLSX_EXT or output_extension == "": + result_file = f"FOSSLight_Compare_{_start_time}{XLSX_EXT}" + elif output_extension == HTML_EXT: + result_file = f"FOSSLight_Compare_{_start_time}{HTML_EXT}" + elif output_extension == YAML_EXT: + result_file = f"FOSSLight_Compare_{_start_time}{YAML_EXT}" + elif output_extension == JSON_EXT: + result_file = f"FOSSLight_Compare_{_start_time}{JSON_EXT}" else: logger.error("Not supported file extension") @@ -224,13 +230,29 @@ def count_compared_result(compared_result): logger.info(f"Comparison result: {count_str}") -def run_compare(before_yaml, after_yaml, output_path, output_file, file_ext, _start_time): +def run_compare(before_f, after_f, output_path, output_file, file_ext, _start_time): ret = False logger.info("Start compare mode") - logger.info(f"before file: {before_yaml}") - logger.info(f"after file: {after_yaml}") + logger.info(f"before file: {before_f}") + logger.info(f"after file: {after_f}") + + before_ext = f'.{os.path.basename(before_f).split(".")[-1]}' + after_ext = f'.{os.path.basename(after_f).split(".")[-1]}' + if before_ext != after_ext: + logger.error("Please enter the two FOSSLight report with the same file extension.") + return False + if before_ext not in [YAML_EXT, XLSX_EXT]: + logger.error(f"Compare mode only supports 'yaml' or 'xlsx' extension. (input extension:{before_ext})") + return False + else: + before_yaml = before_f if before_ext == YAML_EXT else f'{before_f.rstrip(XLSX_EXT)}{YAML_EXT}' + after_yaml = after_f if after_ext == YAML_EXT else f'{after_f.rstrip(XLSX_EXT)}{YAML_EXT}' result_file = get_comparison_result_filename(output_path, output_file, file_ext, _start_time) + + if before_ext == XLSX_EXT: + convert_excel_to_yaml(before_f, before_yaml) + convert_excel_to_yaml(after_f, after_yaml) compared_result = compare_yaml(before_yaml, after_yaml) if compared_result != '': count_compared_result(compared_result) diff --git a/src/fosslight_scanner/fosslight_scanner.py b/src/fosslight_scanner/fosslight_scanner.py index 085aa6f..d5b1bf0 100755 --- a/src/fosslight_scanner/fosslight_scanner.py +++ b/src/fosslight_scanner/fosslight_scanner.py @@ -282,8 +282,8 @@ def run_main(mode, path_arg, dep_arguments, output_file_or_dir, file_format, url if mode == "compare": CUSTOMIZED_FORMAT = {'excel': '.xlsx', 'html': '.html', 'json': '.json', 'yaml': '.yaml'} if isinstance(path_arg, list) and len(path_arg) == 2: - before_yaml = path_arg[0] - after_yaml = path_arg[1] + before_comp_f = path_arg[0] + after_comp_f = path_arg[1] else: logger.error("Enter two FOSSLight report file with 'p' option.") return False @@ -302,23 +302,22 @@ def run_main(mode, path_arg, dep_arguments, output_file_or_dir, file_format, url sys.exit(1) try: if mode == "compare": - if before_yaml == '' or after_yaml == '': - logger.error("before and after yaml files are necessary.") + if before_comp_f == '' or after_comp_f == '': + logger.error("before and after files are necessary.") return False - if not os.path.exists(os.path.join(_executed_path, before_yaml)): - logger.error("Cannot find before yaml file (1st param with -y option).") + if not os.path.exists(os.path.join(_executed_path, before_comp_f)): + logger.error("Cannot find before FOSSLight report file (1st param with -y option).") return False - if not os.path.exists(os.path.join(_executed_path, after_yaml)): - logger.error("Cannot find after yaml file (2nd param with -y option).") + if not os.path.exists(os.path.join(_executed_path, after_comp_f)): + logger.error("Cannot find after FOSSLight report file (2nd param with -y option).") return False - ret, final_excel_dir, result_log = init(output_path, False) if output_path == "": output_path = _executed_path else: output_path = os.path.abspath(output_path) - run_compare(os.path.join(_executed_path, before_yaml), os.path.join(_executed_path, after_yaml), + run_compare(os.path.join(_executed_path, before_comp_f), os.path.join(_executed_path, after_comp_f), output_path, output_file, output_extension, _start_time) else: run_src = False