diff --git a/pyproject.toml b/pyproject.toml index a272802..a6ef1a6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ dependencies = [ "pyyaml", "beautifulsoup4", "fosslight_util>=2.1.47,<3.0.0", - "fosslight_source>=2.2.16,<3.0.0", + "fosslight_source>=2.3.3,<3.0.0", "fosslight_dependency>=4.1.31,<5.0.0", "fosslight_binary>=5.1.17,<6.0.0", ] diff --git a/src/fosslight_scanner/_help.py b/src/fosslight_scanner/_help.py index 57cdfc0..a14bcc8 100644 --- a/src/fosslight_scanner/_help.py +++ b/src/fosslight_scanner/_help.py @@ -66,6 +66,7 @@ For 'all' or 'source' mode: --kb_url KB API URL for source analysis --kb_token KB API bearer token for source analysis + --no_merge Keep source paths file-based without folder merge 💡 Examples ──────────────────────────────────────────────────────────────────── diff --git a/src/fosslight_scanner/_parse_setting.py b/src/fosslight_scanner/_parse_setting.py index fcb722e..b77bfea 100644 --- a/src/fosslight_scanner/_parse_setting.py +++ b/src/fosslight_scanner/_parse_setting.py @@ -28,12 +28,14 @@ def parse_setting_json(data): kb_token = data.get('kb_token', '') binary_simple = data.get('binary_simple', False) recursive_dep = data.get('recursive_dep', False) + no_merge = data.get('no_merge', False) str_lists = [mode, path, exclude_path] strings = [ dep_argument, output, format, db_url, correct_fpath, link, selected_source_scanner, kb_url, kb_token ] - booleans = [timer, raw, no_correction, ui, source_write_json_file, source_print_matched_text, binary_simple, recursive_dep] + booleans = [timer, raw, no_correction, ui, source_write_json_file, + source_print_matched_text, binary_simple, recursive_dep, no_merge] is_incorrect = False @@ -68,4 +70,4 @@ def parse_setting_json(data): return mode, path, dep_argument, output, format, link, db_url, timer, \ raw, core, no_correction, correct_fpath, ui, exclude_path, \ selected_source_scanner, source_write_json_file, source_print_matched_text, source_time_out, \ - binary_simple, recursive_dep, kb_url, kb_token + binary_simple, recursive_dep, kb_url, kb_token, no_merge diff --git a/src/fosslight_scanner/cli.py b/src/fosslight_scanner/cli.py index 99f9363..8842cff 100644 --- a/src/fosslight_scanner/cli.py +++ b/src/fosslight_scanner/cli.py @@ -16,7 +16,7 @@ def set_args(mode, path, dep_argument, output, format, link, db_url, timer, raw, core, no_correction, correct_fpath, ui, setting, exclude_path, - recursive_dep, kb_url="", kb_token=""): + recursive_dep, kb_url="", kb_token="", no_merge=False): selected_source_scanner = "all" source_write_json_file = False @@ -31,7 +31,7 @@ def set_args(mode, path, dep_argument, output, format, link, db_url, timer, s_mode, s_path, s_dep_argument, s_output, s_format, s_link, s_db_url, s_timer, s_raw, s_core, \ s_no_correction, s_correct_fpath, s_ui, s_exclude_path, \ s_selected_source_scanner, s_source_write_json_file, s_source_print_matched_text, \ - s_source_time_out, s_binary_simple, s_recursive_dep, s_kb_url, s_kb_token = parse_setting_json(data) + s_source_time_out, s_binary_simple, s_recursive_dep, s_kb_url, s_kb_token, s_no_merge = parse_setting_json(data) # direct cli arguments have higher priority than setting file mode = mode or s_mode @@ -51,6 +51,7 @@ def set_args(mode, path, dep_argument, output, format, link, db_url, timer, recursive_dep = recursive_dep or s_recursive_dep kb_url = kb_url or s_kb_url kb_token = kb_token or s_kb_token + no_merge = no_merge or s_no_merge # These options are only set from the setting file, not from CLI arguments selected_source_scanner = s_selected_source_scanner or selected_source_scanner @@ -64,7 +65,7 @@ def set_args(mode, path, dep_argument, output, format, link, db_url, timer, return mode, path, dep_argument, output, format, link, db_url, timer, \ raw, core, no_correction, correct_fpath, ui, exclude_path, \ selected_source_scanner, source_write_json_file, source_print_matched_text, source_time_out, \ - binary_simple, recursive_dep, kb_url, kb_token + binary_simple, recursive_dep, kb_url, kb_token, no_merge def main(): @@ -115,6 +116,8 @@ def main(): type=str, dest='kb_url', default="") parser.add_argument('--kb_token', help='KB API bearer token for source analysis', type=str, dest='kb_token', default="") + parser.add_argument('--no_merge', help='Keep source paths file-based without folder merge', + action='store_true', dest='no_merge', required=False, default=False) try: args = parser.parse_args() @@ -128,17 +131,17 @@ def main(): else: mode, path, dep_argument, output, format, link, db_url, timer, raw, core, no_correction, correct_fpath, \ ui, exclude_path, selected_source_scanner, source_write_json_file, source_print_matched_text, \ - source_time_out, binary_simple, recursive_dep, kb_url, kb_token = set_args( + source_time_out, binary_simple, recursive_dep, kb_url, kb_token, no_merge = set_args( args.mode, args.path, args.dep_argument, args.output, args.format, args.link, args.db_url, args.timer, args.raw, args.core, args.no_correction, args.correct_fpath, args.ui, args.setting, args.exclude_path, args.recursive_dep, - args.kb_url, args.kb_token) + args.kb_url, args.kb_token, args.no_merge) run_main(mode, path, dep_argument, output, format, link, db_url, timer, raw, core, not no_correction, correct_fpath, ui, exclude_path, selected_source_scanner, source_write_json_file, source_print_matched_text, - source_time_out, kb_url, kb_token, binary_simple, recursive_dep) + source_time_out, kb_url, kb_token, binary_simple, recursive_dep, no_merge) if __name__ == "__main__": diff --git a/src/fosslight_scanner/fosslight_scanner.py b/src/fosslight_scanner/fosslight_scanner.py index 443f3bc..375e318 100755 --- a/src/fosslight_scanner/fosslight_scanner.py +++ b/src/fosslight_scanner/fosslight_scanner.py @@ -152,7 +152,8 @@ def run_scanner(src_path, dep_arguments, output_path, keep_raw_data=False, default_oss_name="", default_oss_version="", url="", correct_mode=True, correct_fpath="", ui_mode=False, path_to_exclude=[], selected_source_scanner="all", source_write_json_file=False, source_print_matched_text=False, - source_time_out=120, kb_url="", kb_token="", binary_simple=False, formats=[], recursive_dep=False): + source_time_out=120, kb_url="", kb_token="", binary_simple=False, formats=[], + recursive_dep=False, no_merge=False): final_excel_dir = output_path final_reports = [] @@ -230,6 +231,7 @@ def run_scanner(src_path, dep_arguments, output_path, keep_raw_data=False, kb_url=kb_url, kb_token=kb_token, formats=formats, + merge_by_folder=not no_merge, all_exclude_mode=_all_exclude_mode_for_scanner( excluded_path_with_default_exclusion, excluded_path_without_dot, @@ -250,6 +252,8 @@ def run_scanner(src_path, dep_arguments, output_path, keep_raw_data=False, command += f" --kb_url {shlex.quote(kb_url)}" if kb_token: command += f" --kb_token {shlex.quote(kb_token)}" + if no_merge: + command += " --no_merge" command_result = subprocess.run(command, stdout=subprocess.PIPE, text=True) logger.info(f"Source Analysis Result:{command_result.stdout}") @@ -400,7 +404,8 @@ def run_main(mode_list, path_arg, dep_arguments, output_file_or_dir, file_format db_url, hide_progressbar=False, keep_raw_data=False, num_cores=-1, correct_mode=True, correct_fpath="", ui_mode=False, path_to_exclude=[], selected_source_scanner="all", source_write_json_file=False, source_print_matched_text=False, - source_time_out=120, kb_url="", kb_token="", binary_simple=False, recursive_dep=False): + source_time_out=120, kb_url="", kb_token="", binary_simple=False, + recursive_dep=False, no_merge=False): global _executed_path output_files = [] @@ -512,7 +517,8 @@ def run_main(mode_list, path_arg, dep_arguments, output_file_or_dir, file_format default_oss_name, default_oss_version, url_to_analyze, correct_mode, correct_fpath, ui_mode, path_to_exclude, selected_source_scanner, source_write_json_file, source_print_matched_text, - source_time_out, kb_url, kb_token, binary_simple, formats, recursive_dep) + source_time_out, kb_url, + kb_token, binary_simple, formats, recursive_dep, no_merge) if extract_folder: shutil.rmtree(extract_folder) diff --git a/tests/fixtures/setting.json b/tests/fixtures/setting.json index 348f87d..17638c6 100644 --- a/tests/fixtures/setting.json +++ b/tests/fixtures/setting.json @@ -1,9 +1,16 @@ { - "mode": ["binary", "source"], - "path": ["tests/fixtures/scan_project"], + "mode": [ + "binary", + "source" + ], + "path": [ + "tests/fixtures/scan_project" + ], "dep_argument": "", "output": "test_result_dir", - "format": ["excel"], + "format": [ + "excel" + ], "link": "", "db_url": "", "timer": false, @@ -12,7 +19,10 @@ "no_correction": false, "correct_fpath": "", "ui": false, - "exclude": ["test", "sample_license.txt"], + "exclude": [ + "test", + "sample_license.txt" + ], "selected_source_scanner": "scancode", "source_write_json_file": true, "source_print_matched_text": true, @@ -20,5 +30,6 @@ "kb_url": "", "kb_token": "", "binary_simple": false, - "recursive_dep": false -} + "recursive_dep": false, + "no_merge": false +} \ No newline at end of file diff --git a/tests/test__parse_setting.py b/tests/test__parse_setting.py index e5c946c..662b568 100644 --- a/tests/test__parse_setting.py +++ b/tests/test__parse_setting.py @@ -34,5 +34,5 @@ def test_parse_setting_json_valid_data(): assert result == ( ['test'], ['/some/path'], 'arg', 'output', 'json', 'http://example.com', 'sqlite:///:memory:', True, True, 4, True, '/correct/path', True, ['/exclude/path'], 'scanner', True, True, 60, True, False, - 'http://kb.example.com', 'test_token' + 'http://kb.example.com', 'test_token', False ) diff --git a/tests/test_cli.py b/tests/test_cli.py index b4ba073..d805ed0 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -55,7 +55,7 @@ def mock_open(*args, **kwargs): expected = ( ["test_mode"], ["test_path"], "test_dep_argument", "test_output", ["test_format"], "test_link", "test_db_url", True, True, 4, True, "test_correct_fpath", True, ["test_exclude_path"], "test_scanner", True, True, 100, True, False, - "http://kb.example.com", "test_token" + "http://kb.example.com", "test_token", False ) assert result == expected