fosslight-scanner 2.1.9__tar.gz → 2.1.11__tar.gz
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.
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/PKG-INFO +24 -2
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/setup.py +1 -1
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner/_help.py +9 -7
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner/_parse_setting.py +3 -2
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner/cli.py +11 -7
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner/fosslight_scanner.py +10 -6
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner.egg-info/PKG-INFO +25 -3
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner.egg-info/SOURCES.txt +8 -1
- fosslight_scanner-2.1.11/tests/test__get_input.py +44 -0
- fosslight_scanner-2.1.11/tests/test__help.py +22 -0
- fosslight_scanner-2.1.11/tests/test__parse_setting.py +35 -0
- fosslight_scanner-2.1.11/tests/test__run_compare.py +199 -0
- fosslight_scanner-2.1.11/tests/test_cli.py +72 -0
- fosslight_scanner-2.1.11/tests/test_common.py +192 -0
- fosslight_scanner-2.1.11/tests/test_fosslight_scanner.py +150 -0
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/LICENSE +0 -0
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/MANIFEST.in +0 -0
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/README.md +0 -0
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/requirements.txt +0 -0
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/setup.cfg +0 -0
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner/__init__.py +0 -0
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner/_get_input.py +0 -0
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner/_run_compare.py +0 -0
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner/common.py +0 -0
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner/resources/bom_compare.html +0 -0
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner.egg-info/dependency_links.txt +0 -0
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner.egg-info/entry_points.txt +0 -0
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner.egg-info/requires.txt +0 -0
- {fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: fosslight_scanner
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.11
|
|
4
4
|
Summary: FOSSLight Scanner
|
|
5
5
|
Home-page: https://github.com/fosslight/fosslight_scanner
|
|
6
6
|
Download-URL: https://github.com/fosslight/fosslight_scanner
|
|
@@ -14,6 +14,28 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
14
14
|
Requires-Python: >=3.10,<3.13
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
License-File: LICENSE
|
|
17
|
+
Requires-Dist: future
|
|
18
|
+
Requires-Dist: pandas
|
|
19
|
+
Requires-Dist: openpyxl
|
|
20
|
+
Requires-Dist: progress
|
|
21
|
+
Requires-Dist: pyyaml
|
|
22
|
+
Requires-Dist: beautifulsoup4
|
|
23
|
+
Requires-Dist: fosslight_util<3.0.0,>=2.1.12
|
|
24
|
+
Requires-Dist: fosslight_source<3.0.0,>=2.1.12
|
|
25
|
+
Requires-Dist: fosslight_dependency<5.0.0,>=4.1.3
|
|
26
|
+
Requires-Dist: fosslight_binary<6.0.0,>=5.1.9
|
|
27
|
+
Requires-Dist: fosslight_prechecker<5.0.0,>=4.0.0
|
|
28
|
+
Dynamic: author
|
|
29
|
+
Dynamic: classifier
|
|
30
|
+
Dynamic: description
|
|
31
|
+
Dynamic: description-content-type
|
|
32
|
+
Dynamic: download-url
|
|
33
|
+
Dynamic: home-page
|
|
34
|
+
Dynamic: license
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
Dynamic: requires-dist
|
|
37
|
+
Dynamic: requires-python
|
|
38
|
+
Dynamic: summary
|
|
17
39
|
|
|
18
40
|
<!--
|
|
19
41
|
Copyright (c) 2021 LG Electronics
|
|
@@ -15,7 +15,7 @@ with open('requirements.txt', 'r', 'utf-8') as f:
|
|
|
15
15
|
if __name__ == "__main__":
|
|
16
16
|
setup(
|
|
17
17
|
name='fosslight_scanner',
|
|
18
|
-
version='2.1.
|
|
18
|
+
version='2.1.11',
|
|
19
19
|
package_dir={"": "src"},
|
|
20
20
|
packages=find_packages(where='src'),
|
|
21
21
|
description='FOSSLight Scanner',
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
# Copyright (c) 2021 LG Electronics Inc.
|
|
4
4
|
# SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
from fosslight_util.help import PrintHelpMsg
|
|
6
|
+
from fosslight_util.output_format import SUPPORT_FORMAT
|
|
6
7
|
|
|
7
|
-
_HELP_MESSAGE_SCANNER = """
|
|
8
|
+
_HELP_MESSAGE_SCANNER = f"""
|
|
8
9
|
FOSSLight Scanner performs open source analysis after downloading the source from URL that can be cloned by git or wget.
|
|
9
10
|
Instead, open source analysis and checking copyright/license rules can be performed for the local source path.
|
|
10
11
|
The output result is generated in OSS Report format.
|
|
@@ -21,14 +22,14 @@ _HELP_MESSAGE_SCANNER = """
|
|
|
21
22
|
|
|
22
23
|
Options:
|
|
23
24
|
-h\t\t\t Print help message
|
|
24
|
-
-p <path>\t\t Path to analyze (ex, -p
|
|
25
|
+
-p <path>\t\t Path to analyze (ex, -p [input_path])
|
|
25
26
|
* Compare mode input file: Two FOSSLight reports (supports excel, yaml)
|
|
26
|
-
(ex, -p
|
|
27
|
+
(ex, -p [before_name].xlsx [after_name].xlsx)
|
|
27
28
|
-w <link>\t\t Link to be analyzed can be downloaded by wget or git clone
|
|
28
|
-
-f <formats> [<format> ...]\t FOSSLight Report file format (
|
|
29
|
+
-f <formats> [<format> ...]\t FOSSLight Report file format ({', '.join(SUPPORT_FORMAT)})
|
|
29
30
|
* Compare mode result file: supports excel, json, yaml, html
|
|
30
31
|
* Multiple formats can be specified separated by space.
|
|
31
|
-
-e <path>\t\t Path to exclude from analysis (ex, -e
|
|
32
|
+
-e <path>\t\t Path to exclude from analysis (ex, -e [dir] [file])
|
|
32
33
|
-o <output>\t\t Output directory or file
|
|
33
34
|
-c <number>\t\t Number of processes to analyze source
|
|
34
35
|
-r\t\t\t Keep raw data
|
|
@@ -40,13 +41,14 @@ _HELP_MESSAGE_SCANNER = """
|
|
|
40
41
|
--no_correction\t Enter if you don't want to correct OSS information with sbom-info.yaml
|
|
41
42
|
* Correction mode only supported xlsx format.
|
|
42
43
|
--correct_fpath <path> Path to the sbom-info.yaml file
|
|
43
|
-
--ui\t\t
|
|
44
|
+
--ui\t\t Generate UI mode result file
|
|
45
|
+
--recursive_dep\t Recursively analyze dependencies
|
|
44
46
|
|
|
45
47
|
Options for only 'all' or 'bin' mode
|
|
46
48
|
-u <db_url>\t\t DB Connection(format :'postgresql://username:password@host:port/database_name')
|
|
47
49
|
|
|
48
50
|
Options for only 'all' or 'dependency' mode
|
|
49
|
-
-d <
|
|
51
|
+
-d <dependency_arg>\t Additional arguments for running dependency analysis"""
|
|
50
52
|
|
|
51
53
|
|
|
52
54
|
def print_help_msg():
|
{fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner/_parse_setting.py
RENAMED
|
@@ -25,12 +25,13 @@ def parse_setting_json(data):
|
|
|
25
25
|
source_print_matched_text = data.get('source_print_matched_text', False)
|
|
26
26
|
source_time_out = data.get('source_time_out', 120)
|
|
27
27
|
binary_simple = data.get('binary_simple', False)
|
|
28
|
+
recursive_dep = data.get('recursive_dep', False)
|
|
28
29
|
str_lists = [mode, path, exclude_path]
|
|
29
30
|
strings = [
|
|
30
31
|
dep_argument, output, format, db_url,
|
|
31
32
|
correct_fpath, link, selected_source_scanner
|
|
32
33
|
]
|
|
33
|
-
booleans = [timer, raw, no_correction, ui, source_write_json_file, source_print_matched_text, binary_simple]
|
|
34
|
+
booleans = [timer, raw, no_correction, ui, source_write_json_file, source_print_matched_text, binary_simple, recursive_dep]
|
|
34
35
|
|
|
35
36
|
is_incorrect = False
|
|
36
37
|
|
|
@@ -65,4 +66,4 @@ def parse_setting_json(data):
|
|
|
65
66
|
return mode, path, dep_argument, output, format, link, db_url, timer, \
|
|
66
67
|
raw, core, no_correction, correct_fpath, ui, exclude_path, \
|
|
67
68
|
selected_source_scanner, source_write_json_file, source_print_matched_text, source_time_out, \
|
|
68
|
-
binary_simple
|
|
69
|
+
binary_simple, recursive_dep
|
|
@@ -15,7 +15,8 @@ from fosslight_util.help import print_package_version
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
def set_args(mode, path, dep_argument, output, format, link, db_url, timer,
|
|
18
|
-
raw, core, no_correction, correct_fpath, ui, setting, exclude_path
|
|
18
|
+
raw, core, no_correction, correct_fpath, ui, setting, exclude_path,
|
|
19
|
+
recursive_dep):
|
|
19
20
|
|
|
20
21
|
selected_source_scanner = "all"
|
|
21
22
|
source_write_json_file = False
|
|
@@ -30,7 +31,7 @@ def set_args(mode, path, dep_argument, output, format, link, db_url, timer,
|
|
|
30
31
|
s_mode, s_path, s_dep_argument, s_output, s_format, s_link, s_db_url, s_timer, s_raw, s_core, \
|
|
31
32
|
s_no_correction, s_correct_fpath, s_ui, s_exclude_path, \
|
|
32
33
|
s_selected_source_scanner, s_source_write_json_file, s_source_print_matched_text, \
|
|
33
|
-
s_source_time_out, s_binary_simple = parse_setting_json(data)
|
|
34
|
+
s_source_time_out, s_binary_simple, s_recursive_dep = parse_setting_json(data)
|
|
34
35
|
|
|
35
36
|
# direct cli arguments have higher priority than setting file
|
|
36
37
|
mode = mode or s_mode
|
|
@@ -47,6 +48,7 @@ def set_args(mode, path, dep_argument, output, format, link, db_url, timer,
|
|
|
47
48
|
correct_fpath = correct_fpath or s_correct_fpath
|
|
48
49
|
ui = ui or s_ui
|
|
49
50
|
exclude_path = exclude_path or s_exclude_path
|
|
51
|
+
recursive_dep = recursive_dep or s_recursive_dep
|
|
50
52
|
|
|
51
53
|
# These options are only set from the setting file, not from CLI arguments
|
|
52
54
|
selected_source_scanner = s_selected_source_scanner or selected_source_scanner
|
|
@@ -60,7 +62,7 @@ def set_args(mode, path, dep_argument, output, format, link, db_url, timer,
|
|
|
60
62
|
return mode, path, dep_argument, output, format, link, db_url, timer, \
|
|
61
63
|
raw, core, no_correction, correct_fpath, ui, exclude_path, \
|
|
62
64
|
selected_source_scanner, source_write_json_file, source_print_matched_text, source_time_out, \
|
|
63
|
-
binary_simple
|
|
65
|
+
binary_simple, recursive_dep
|
|
64
66
|
|
|
65
67
|
|
|
66
68
|
def main():
|
|
@@ -79,7 +81,7 @@ def main():
|
|
|
79
81
|
type=str, dest='format',nargs='*', default=[])
|
|
80
82
|
parser.add_argument('--output', '-o', help='Output directory or file',
|
|
81
83
|
type=str, dest='output', default="")
|
|
82
|
-
parser.add_argument('--dependency', '-d', help='Dependency arguments',
|
|
84
|
+
parser.add_argument('--dependency', '-d', help='Dependency arguments (e.g. -d "-m pip" )',
|
|
83
85
|
type=str, dest='dep_argument', default="")
|
|
84
86
|
parser.add_argument('--url', '-u', help="DB Url",
|
|
85
87
|
type=str, dest='db_url', default="")
|
|
@@ -105,6 +107,8 @@ def main():
|
|
|
105
107
|
type=str, required=False, default='')
|
|
106
108
|
parser.add_argument('--ui', help='Generate UI mode result file',
|
|
107
109
|
action='store_true', required=False, default=False)
|
|
110
|
+
parser.add_argument('--recursive_dep', '-rd', help='Recursively analyze dependencies',
|
|
111
|
+
action='store_true', dest='recursive_dep', default=False)
|
|
108
112
|
|
|
109
113
|
try:
|
|
110
114
|
args = parser.parse_args()
|
|
@@ -118,16 +122,16 @@ def main():
|
|
|
118
122
|
else:
|
|
119
123
|
mode, path, dep_argument, output, format, link, db_url, timer, raw, core, no_correction, correct_fpath, \
|
|
120
124
|
ui, exclude_path, selected_source_scanner, source_write_json_file, source_print_matched_text, \
|
|
121
|
-
source_time_out, binary_simple, = set_args(
|
|
125
|
+
source_time_out, binary_simple, recursive_dep = set_args(
|
|
122
126
|
args.mode, args.path, args.dep_argument, args.output,
|
|
123
127
|
args.format, args.link, args.db_url, args.timer, args.raw,
|
|
124
128
|
args.core, args.no_correction, args.correct_fpath, args.ui,
|
|
125
|
-
args.setting, args.exclude_path)
|
|
129
|
+
args.setting, args.exclude_path, args.recursive_dep)
|
|
126
130
|
|
|
127
131
|
run_main(mode, path, dep_argument, output, format, link, db_url, timer,
|
|
128
132
|
raw, core, not no_correction, correct_fpath, ui, exclude_path,
|
|
129
133
|
selected_source_scanner, source_write_json_file, source_print_matched_text,
|
|
130
|
-
source_time_out, binary_simple)
|
|
134
|
+
source_time_out, binary_simple, recursive_dep)
|
|
131
135
|
|
|
132
136
|
|
|
133
137
|
if __name__ == "__main__":
|
{fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner/fosslight_scanner.py
RENAMED
|
@@ -57,7 +57,8 @@ SCANNER_MODE = [
|
|
|
57
57
|
]
|
|
58
58
|
|
|
59
59
|
|
|
60
|
-
def run_dependency(path_to_analyze, output_file_with_path, params="", path_to_exclude=[], formats=[]
|
|
60
|
+
def run_dependency(path_to_analyze, output_file_with_path, params="", path_to_exclude=[], formats=[],
|
|
61
|
+
recursive_dep=False):
|
|
61
62
|
result = []
|
|
62
63
|
|
|
63
64
|
package_manager = ""
|
|
@@ -100,7 +101,9 @@ def run_dependency(path_to_analyze, output_file_with_path, params="", path_to_ex
|
|
|
100
101
|
output_file_with_path,
|
|
101
102
|
pip_activate_cmd, pip_deactivate_cmd,
|
|
102
103
|
output_custom_dir, app_name,
|
|
103
|
-
github_token, formats, True, path_to_exclude=path_to_exclude
|
|
104
|
+
github_token, formats, True, path_to_exclude=path_to_exclude,
|
|
105
|
+
graph_path="", graph_size=(600,600),
|
|
106
|
+
recursive=recursive_dep
|
|
104
107
|
)
|
|
105
108
|
if success:
|
|
106
109
|
result = scan_item
|
|
@@ -131,7 +134,7 @@ def run_scanner(src_path, dep_arguments, output_path, keep_raw_data=False,
|
|
|
131
134
|
default_oss_name="", default_oss_version="", url="",
|
|
132
135
|
correct_mode=True, correct_fpath="", ui_mode=False, path_to_exclude=[],
|
|
133
136
|
selected_source_scanner="all", source_write_json_file=False, source_print_matched_text=False,
|
|
134
|
-
source_time_out=120, binary_simple=False, formats=[]):
|
|
137
|
+
source_time_out=120, binary_simple=False, formats=[], recursive_dep=False):
|
|
135
138
|
final_excel_dir = output_path
|
|
136
139
|
success = True
|
|
137
140
|
all_cover_items = []
|
|
@@ -232,7 +235,8 @@ def run_scanner(src_path, dep_arguments, output_path, keep_raw_data=False,
|
|
|
232
235
|
|
|
233
236
|
if run_dep:
|
|
234
237
|
dep_scanitem = run_dependency(src_path, _output_dir,
|
|
235
|
-
dep_arguments, path_to_exclude, formats
|
|
238
|
+
dep_arguments, path_to_exclude, formats,
|
|
239
|
+
recursive_dep)
|
|
236
240
|
all_scan_item.file_items.update(dep_scanitem.file_items)
|
|
237
241
|
all_cover_items.append(dep_scanitem.cover)
|
|
238
242
|
else:
|
|
@@ -359,7 +363,7 @@ def run_main(mode_list, path_arg, dep_arguments, output_file_or_dir, file_format
|
|
|
359
363
|
db_url, hide_progressbar=False, keep_raw_data=False, num_cores=-1,
|
|
360
364
|
correct_mode=True, correct_fpath="", ui_mode=False, path_to_exclude=[],
|
|
361
365
|
selected_source_scanner="all", source_write_json_file=False, source_print_matched_text=False,
|
|
362
|
-
source_time_out=120, binary_simple=False):
|
|
366
|
+
source_time_out=120, binary_simple=False, recursive_dep=False):
|
|
363
367
|
global _executed_path, _start_time
|
|
364
368
|
|
|
365
369
|
output_files = []
|
|
@@ -470,7 +474,7 @@ def run_main(mode_list, path_arg, dep_arguments, output_file_or_dir, file_format
|
|
|
470
474
|
default_oss_name, default_oss_version, url_to_analyze,
|
|
471
475
|
correct_mode, correct_fpath, ui_mode, path_to_exclude,
|
|
472
476
|
selected_source_scanner, source_write_json_file, source_print_matched_text, source_time_out,
|
|
473
|
-
binary_simple, formats)
|
|
477
|
+
binary_simple, formats, recursive_dep)
|
|
474
478
|
|
|
475
479
|
if extract_folder:
|
|
476
480
|
shutil.rmtree(extract_folder)
|
{fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner.egg-info/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
2
|
-
Name:
|
|
3
|
-
Version: 2.1.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fosslight_scanner
|
|
3
|
+
Version: 2.1.11
|
|
4
4
|
Summary: FOSSLight Scanner
|
|
5
5
|
Home-page: https://github.com/fosslight/fosslight_scanner
|
|
6
6
|
Download-URL: https://github.com/fosslight/fosslight_scanner
|
|
@@ -14,6 +14,28 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
14
14
|
Requires-Python: >=3.10,<3.13
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
License-File: LICENSE
|
|
17
|
+
Requires-Dist: future
|
|
18
|
+
Requires-Dist: pandas
|
|
19
|
+
Requires-Dist: openpyxl
|
|
20
|
+
Requires-Dist: progress
|
|
21
|
+
Requires-Dist: pyyaml
|
|
22
|
+
Requires-Dist: beautifulsoup4
|
|
23
|
+
Requires-Dist: fosslight_util<3.0.0,>=2.1.12
|
|
24
|
+
Requires-Dist: fosslight_source<3.0.0,>=2.1.12
|
|
25
|
+
Requires-Dist: fosslight_dependency<5.0.0,>=4.1.3
|
|
26
|
+
Requires-Dist: fosslight_binary<6.0.0,>=5.1.9
|
|
27
|
+
Requires-Dist: fosslight_prechecker<5.0.0,>=4.0.0
|
|
28
|
+
Dynamic: author
|
|
29
|
+
Dynamic: classifier
|
|
30
|
+
Dynamic: description
|
|
31
|
+
Dynamic: description-content-type
|
|
32
|
+
Dynamic: download-url
|
|
33
|
+
Dynamic: home-page
|
|
34
|
+
Dynamic: license
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
Dynamic: requires-dist
|
|
37
|
+
Dynamic: requires-python
|
|
38
|
+
Dynamic: summary
|
|
17
39
|
|
|
18
40
|
<!--
|
|
19
41
|
Copyright (c) 2021 LG Electronics
|
{fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner.egg-info/SOURCES.txt
RENAMED
|
@@ -17,4 +17,11 @@ src/fosslight_scanner.egg-info/dependency_links.txt
|
|
|
17
17
|
src/fosslight_scanner.egg-info/entry_points.txt
|
|
18
18
|
src/fosslight_scanner.egg-info/requires.txt
|
|
19
19
|
src/fosslight_scanner.egg-info/top_level.txt
|
|
20
|
-
src/fosslight_scanner/resources/bom_compare.html
|
|
20
|
+
src/fosslight_scanner/resources/bom_compare.html
|
|
21
|
+
tests/test__get_input.py
|
|
22
|
+
tests/test__help.py
|
|
23
|
+
tests/test__parse_setting.py
|
|
24
|
+
tests/test__run_compare.py
|
|
25
|
+
tests/test_cli.py
|
|
26
|
+
tests/test_common.py
|
|
27
|
+
tests/test_fosslight_scanner.py
|
|
@@ -0,0 +1,44 @@
|
|
|
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
|
+
|
|
7
|
+
from fosslight_scanner._get_input import get_input, get_input_mode
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_get_input(monkeypatch):
|
|
11
|
+
# given
|
|
12
|
+
ask_msg = "Please enter the path to analyze:"
|
|
13
|
+
default_value = "default"
|
|
14
|
+
|
|
15
|
+
# when
|
|
16
|
+
# Mock input to return an empty string
|
|
17
|
+
monkeypatch.setattr('builtins.input', lambda _: "")
|
|
18
|
+
result_no_input = get_input(ask_msg, default_value)
|
|
19
|
+
|
|
20
|
+
# Mock input to return "user_input"
|
|
21
|
+
monkeypatch.setattr('builtins.input', lambda _: "user_input")
|
|
22
|
+
result_with_input = get_input(ask_msg, "user_input")
|
|
23
|
+
|
|
24
|
+
# then
|
|
25
|
+
assert result_no_input == "default"
|
|
26
|
+
assert result_with_input == "user_input"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_get_input_mode(monkeypatch):
|
|
30
|
+
# given
|
|
31
|
+
executed_path = ""
|
|
32
|
+
mode_list = ["all", "dep"]
|
|
33
|
+
|
|
34
|
+
# Mock ask_to_run to return a predetermined input value
|
|
35
|
+
monkeypatch.setattr('fosslight_scanner._get_input.ask_to_run', lambda _: "1")
|
|
36
|
+
|
|
37
|
+
# Mock input to provide other necessary return values
|
|
38
|
+
monkeypatch.setattr('builtins.input', lambda _: "https://example.com")
|
|
39
|
+
|
|
40
|
+
# when
|
|
41
|
+
_, _, url_to_analyze = get_input_mode(executed_path, mode_list)
|
|
42
|
+
|
|
43
|
+
# then
|
|
44
|
+
assert url_to_analyze == "https://example.com"
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
|
|
7
|
+
import sys
|
|
8
|
+
from fosslight_scanner._help import print_help_msg, _HELP_MESSAGE_SCANNER
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_print_help_msg(capsys, monkeypatch):
|
|
12
|
+
# given
|
|
13
|
+
# monkeypatch sys.exit to prevent the test from stopping
|
|
14
|
+
monkeypatch.setattr(sys, "exit", lambda: None)
|
|
15
|
+
|
|
16
|
+
# when
|
|
17
|
+
print_help_msg()
|
|
18
|
+
|
|
19
|
+
# then
|
|
20
|
+
captured = capsys.readouterr()
|
|
21
|
+
# Validate the help message output
|
|
22
|
+
assert _HELP_MESSAGE_SCANNER.strip() in captured.out
|
|
@@ -0,0 +1,35 @@
|
|
|
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
|
+
from fosslight_scanner._parse_setting import parse_setting_json
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def test_parse_setting_json_valid_data():
|
|
10
|
+
data = {
|
|
11
|
+
'mode': ['test'],
|
|
12
|
+
'path': ['/some/path'],
|
|
13
|
+
'dep_argument': 'arg',
|
|
14
|
+
'output': 'output',
|
|
15
|
+
'format': 'json',
|
|
16
|
+
'link': 'http://example.com',
|
|
17
|
+
'db_url': 'sqlite:///:memory:',
|
|
18
|
+
'timer': True,
|
|
19
|
+
'raw': True,
|
|
20
|
+
'core': 4,
|
|
21
|
+
'no_correction': True,
|
|
22
|
+
'correct_fpath': '/correct/path',
|
|
23
|
+
'ui': True,
|
|
24
|
+
'exclude': ['/exclude/path'],
|
|
25
|
+
'selected_source_scanner': 'scanner',
|
|
26
|
+
'source_write_json_file': True,
|
|
27
|
+
'source_print_matched_text': True,
|
|
28
|
+
'source_time_out': 60,
|
|
29
|
+
'binary_simple': True
|
|
30
|
+
}
|
|
31
|
+
result = parse_setting_json(data)
|
|
32
|
+
assert result == (
|
|
33
|
+
['test'], ['/some/path'], 'arg', 'output', 'json', 'http://example.com', 'sqlite:///:memory:', True,
|
|
34
|
+
True, 4, True, '/correct/path', True, ['/exclude/path'], 'scanner', True, True, 60, True, False
|
|
35
|
+
)
|
|
@@ -0,0 +1,199 @@
|
|
|
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
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
from fosslight_scanner._run_compare import write_result_json_yaml, parse_result_for_table, get_sample_html, \
|
|
9
|
+
write_result_html, write_result_xlsx, write_compared_result, get_comparison_result_filename, \
|
|
10
|
+
count_compared_result, run_compare, \
|
|
11
|
+
ADD, DELETE, CHANGE, XLSX_EXT, HTML_EXT, YAML_EXT, JSON_EXT
|
|
12
|
+
import logging
|
|
13
|
+
import json
|
|
14
|
+
import yaml
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@pytest.mark.parametrize("ext, expected_content", [
|
|
18
|
+
# Test for JSON and YAML extensions
|
|
19
|
+
(".json", {"key": "value"}),
|
|
20
|
+
(".yaml", {"key": "value"}),
|
|
21
|
+
|
|
22
|
+
# Test for TXT extension (failure)
|
|
23
|
+
(".txt", {"key": "value"}),
|
|
24
|
+
])
|
|
25
|
+
def test_write_result_json_yaml(tmp_path, ext, expected_content):
|
|
26
|
+
# given
|
|
27
|
+
output_file = tmp_path / f"result{ext}"
|
|
28
|
+
compared_result = expected_content
|
|
29
|
+
|
|
30
|
+
# when
|
|
31
|
+
success = write_result_json_yaml(output_file, compared_result, ext)
|
|
32
|
+
|
|
33
|
+
# then
|
|
34
|
+
assert success is True, f"Failed to write file with extension {ext}"
|
|
35
|
+
|
|
36
|
+
# Verify content based on extension
|
|
37
|
+
if ext == ".json":
|
|
38
|
+
with open(output_file, 'r', encoding='utf-8') as f:
|
|
39
|
+
result_content = json.load(f)
|
|
40
|
+
assert result_content == compared_result, "The content of the JSON file does not match the expected content."
|
|
41
|
+
|
|
42
|
+
elif ext == ".yaml":
|
|
43
|
+
with open(output_file, 'r', encoding='utf-8') as f:
|
|
44
|
+
result_content = yaml.safe_load(f)
|
|
45
|
+
assert result_content == compared_result, "The content of the YAML file does not match the expected content."
|
|
46
|
+
|
|
47
|
+
elif ext == ".txt":
|
|
48
|
+
with open(output_file, 'r', encoding='utf-8') as f:
|
|
49
|
+
result_lines = f.readlines()
|
|
50
|
+
result_content = ''.join(result_lines)
|
|
51
|
+
assert result_content != compared_result, "The content of the TXT file does not match the expected string representation."
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def test_parse_result_for_table():
|
|
55
|
+
# given
|
|
56
|
+
add_expected = [ADD, '', '', 'test(1.0)', 'MIT']
|
|
57
|
+
oi = {"name": "test", "version": "1.0", "license": ["MIT"]}
|
|
58
|
+
|
|
59
|
+
# when
|
|
60
|
+
add_result = parse_result_for_table(oi, ADD)
|
|
61
|
+
|
|
62
|
+
# then
|
|
63
|
+
assert add_result == add_expected
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_get_sample_html():
|
|
67
|
+
# then
|
|
68
|
+
assert get_sample_html() != ''
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@pytest.mark.parametrize("compared_result, expected_before, expected_after", [
|
|
72
|
+
# Case with empty add, delete, change
|
|
73
|
+
({ADD: [], DELETE: [], CHANGE: []}, "before.yaml", "after.yaml"),
|
|
74
|
+
|
|
75
|
+
# Case with one entry in add and no deletes or changes
|
|
76
|
+
({ADD: [{"name": "test", "version": "1.0", "license": ["MIT"]}], DELETE: [], CHANGE: []},
|
|
77
|
+
"before.yaml", "after.yaml")
|
|
78
|
+
])
|
|
79
|
+
def test_write_result_html(tmp_path, compared_result, expected_before, expected_after):
|
|
80
|
+
# given
|
|
81
|
+
output_file = tmp_path / "result.html"
|
|
82
|
+
|
|
83
|
+
# when
|
|
84
|
+
success = write_result_html(output_file, compared_result, expected_before, expected_after)
|
|
85
|
+
|
|
86
|
+
# then
|
|
87
|
+
assert success is True, "Failed to write the HTML file."
|
|
88
|
+
assert output_file.exists(), "The HTML file was not created."
|
|
89
|
+
with open(output_file, 'r', encoding='utf-8') as f:
|
|
90
|
+
content = f.read()
|
|
91
|
+
assert content, "The HTML file is empty."
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@pytest.mark.parametrize("compared_result", [
|
|
95
|
+
# Case with empty add, delete, change
|
|
96
|
+
{ADD: [], DELETE: [], CHANGE: []},
|
|
97
|
+
|
|
98
|
+
# Case with one entry in add and no deletes or changes
|
|
99
|
+
{ADD: [{"name": "test", "version": "1.0", "license": ["MIT"]}], DELETE: [], CHANGE: []}
|
|
100
|
+
])
|
|
101
|
+
def test_write_result_xlsx(tmp_path, compared_result):
|
|
102
|
+
# given
|
|
103
|
+
output_file = tmp_path / "result.xlsx"
|
|
104
|
+
|
|
105
|
+
# when
|
|
106
|
+
success = write_result_xlsx(output_file, compared_result)
|
|
107
|
+
|
|
108
|
+
# then
|
|
109
|
+
assert success is True, "Failed to write the XLSX file."
|
|
110
|
+
assert output_file.exists(), "The XLSX file was not created."
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@pytest.mark.parametrize("ext, expected_output", [
|
|
114
|
+
(XLSX_EXT, "xlsx"),
|
|
115
|
+
(HTML_EXT, "html"),
|
|
116
|
+
(JSON_EXT, "json"),
|
|
117
|
+
(YAML_EXT, "yaml"),
|
|
118
|
+
])
|
|
119
|
+
def test_write_compared_result(tmp_path, ext, expected_output):
|
|
120
|
+
# given
|
|
121
|
+
output_file = tmp_path / "result"
|
|
122
|
+
compared_result = {ADD: [], DELETE: [], CHANGE: []}
|
|
123
|
+
|
|
124
|
+
# when
|
|
125
|
+
success, result_file = write_compared_result(output_file, compared_result, ext)
|
|
126
|
+
|
|
127
|
+
# then
|
|
128
|
+
assert success is True, f"Failed to write the compared result for extension {ext}"
|
|
129
|
+
if ext == XLSX_EXT:
|
|
130
|
+
assert str(result_file) == str(output_file), "The XLSX result file path does not match the expected output path."
|
|
131
|
+
elif ext == HTML_EXT:
|
|
132
|
+
expected_result_file = f"{str(output_file) + XLSX_EXT}, {str(output_file)}"
|
|
133
|
+
assert result_file == expected_result_file, "HTML file creation failed."
|
|
134
|
+
elif ext == JSON_EXT:
|
|
135
|
+
assert str(result_file) == str(output_file), "The JSON result file path does not match the expected output path."
|
|
136
|
+
else:
|
|
137
|
+
assert str(result_file) == str(output_file), "The YAML result file path does not match the expected output path."
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
@pytest.mark.parametrize("path, file_name, ext, time_suffix, expected_output", [
|
|
141
|
+
# Case when file name is provided
|
|
142
|
+
("/path", "file", XLSX_EXT, "time", "/path/file.xlsx"),
|
|
143
|
+
|
|
144
|
+
# Case when file name is empty, with different extensions
|
|
145
|
+
("/path", "", XLSX_EXT, "time", "/path/fosslight_compare_time.xlsx"),
|
|
146
|
+
("/path", "", HTML_EXT, "time", "/path/fosslight_compare_time.html"),
|
|
147
|
+
("/path", "", YAML_EXT, "time", "/path/fosslight_compare_time.yaml"),
|
|
148
|
+
("/path", "", JSON_EXT, "time", "/path/fosslight_compare_time.json"),
|
|
149
|
+
])
|
|
150
|
+
def test_get_comparison_result_filename(path, file_name, ext, time_suffix, expected_output):
|
|
151
|
+
# when
|
|
152
|
+
result = get_comparison_result_filename(path, file_name, ext, time_suffix)
|
|
153
|
+
|
|
154
|
+
# then
|
|
155
|
+
assert result == expected_output, f"Expected {expected_output} but got {result}"
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
@pytest.mark.parametrize("compared_result, expected_log", [
|
|
159
|
+
({ADD: [], DELETE: [], CHANGE: []}, "all oss lists are the same."),
|
|
160
|
+
({ADD: [{"name": "test"}], DELETE: [], CHANGE: []}, "total 1 oss updated (add: 1, delete: 0, change: 0)")
|
|
161
|
+
])
|
|
162
|
+
def test_count_compared_result(compared_result, expected_log, caplog):
|
|
163
|
+
# when
|
|
164
|
+
with caplog.at_level(logging.INFO):
|
|
165
|
+
count_compared_result(compared_result)
|
|
166
|
+
# then
|
|
167
|
+
assert expected_log in caplog.text
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def test_run_compare_different_extension(tmp_path):
|
|
171
|
+
# given
|
|
172
|
+
before_f = tmp_path / "before.yaml"
|
|
173
|
+
after_f = tmp_path / "after.xlsx"
|
|
174
|
+
output_path = tmp_path
|
|
175
|
+
output_file = "result"
|
|
176
|
+
file_ext = ".yaml"
|
|
177
|
+
_start_time = "time"
|
|
178
|
+
_output_dir = tmp_path
|
|
179
|
+
|
|
180
|
+
# Write example content to before_f and after_f
|
|
181
|
+
before_content = {
|
|
182
|
+
"oss_list": [
|
|
183
|
+
{"name": "test", "version": "1.0", "license": "MIT"}
|
|
184
|
+
]
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
# Write these contents to the files
|
|
188
|
+
with open(before_f, "w") as bf:
|
|
189
|
+
yaml.dump(before_content, bf)
|
|
190
|
+
|
|
191
|
+
# Create an empty xlsx file for after_f
|
|
192
|
+
with open(after_f, "w") as af:
|
|
193
|
+
af.write("")
|
|
194
|
+
|
|
195
|
+
# when
|
|
196
|
+
comparison_result = run_compare(before_f, after_f, output_path, output_file, file_ext, _start_time, _output_dir)
|
|
197
|
+
|
|
198
|
+
# then
|
|
199
|
+
assert comparison_result is False
|
|
@@ -0,0 +1,72 @@
|
|
|
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 pytest
|
|
7
|
+
import json
|
|
8
|
+
import sys
|
|
9
|
+
from fosslight_scanner.cli import main, set_args
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_set_args(monkeypatch):
|
|
13
|
+
# Mocking os.path.isfile to return True
|
|
14
|
+
monkeypatch.setattr("os.path.isfile", lambda x: True)
|
|
15
|
+
|
|
16
|
+
# Mocking the open function to return a mock file object
|
|
17
|
+
mock_file_data = json.dumps({
|
|
18
|
+
"mode": ["test_mode"],
|
|
19
|
+
"path": ["test_path"],
|
|
20
|
+
"dep_argument": "test_dep_argument",
|
|
21
|
+
"output": "test_output",
|
|
22
|
+
"format": ["test_format"],
|
|
23
|
+
"link": "test_link",
|
|
24
|
+
"db_url": "test_db_url",
|
|
25
|
+
"timer": True,
|
|
26
|
+
"raw": True,
|
|
27
|
+
"core": 4,
|
|
28
|
+
"no_correction": True,
|
|
29
|
+
"correct_fpath": "test_correct_fpath",
|
|
30
|
+
"ui": True,
|
|
31
|
+
"exclude": ["test_exclude_path"],
|
|
32
|
+
"selected_source_scanner": "test_scanner",
|
|
33
|
+
"source_write_json_file": True,
|
|
34
|
+
"source_print_matched_text": True,
|
|
35
|
+
"source_time_out": 100,
|
|
36
|
+
"binary_simple": True
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
def mock_open(*args, **kwargs):
|
|
40
|
+
from io import StringIO
|
|
41
|
+
return StringIO(mock_file_data)
|
|
42
|
+
|
|
43
|
+
monkeypatch.setattr("builtins.open", mock_open)
|
|
44
|
+
|
|
45
|
+
# Call the function with some arguments
|
|
46
|
+
result = set_args(
|
|
47
|
+
mode=None, path=None, dep_argument=None, output=None, format=None, link=None, db_url=None, timer=None,
|
|
48
|
+
raw=None, core=-1, no_correction=None, correct_fpath=None, ui=None, setting="dummy_path", exclude_path=None,
|
|
49
|
+
recursive_dep=False
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# Expected result
|
|
53
|
+
expected = (
|
|
54
|
+
["test_mode"], ["test_path"], "test_dep_argument", "test_output", ["test_format"], "test_link", "test_db_url", True,
|
|
55
|
+
True, 4, True, "test_correct_fpath", True, ["test_exclude_path"], "test_scanner", True, True, 100, True, False
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
assert result == expected
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def test_main_invalid_option(capsys):
|
|
62
|
+
# given
|
|
63
|
+
test_args = ["fosslight_scanner", "--invalid_option"]
|
|
64
|
+
sys.argv = test_args
|
|
65
|
+
|
|
66
|
+
# when
|
|
67
|
+
with pytest.raises(SystemExit): # 예상되는 SystemExit 처리
|
|
68
|
+
main()
|
|
69
|
+
|
|
70
|
+
# then
|
|
71
|
+
captured = capsys.readouterr()
|
|
72
|
+
assert "unrecognized arguments" in captured.err # 인식되지 않은 인자에 대한 에러 메시지 확인
|
|
@@ -0,0 +1,192 @@
|
|
|
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
|
+
|
|
7
|
+
import os
|
|
8
|
+
import pytest
|
|
9
|
+
from fosslight_scanner.common import copy_file, run_analysis, call_analysis_api, check_package_dir, \
|
|
10
|
+
create_scancodejson, correct_scanner_result
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test_copy_file_success(tmp_path):
|
|
14
|
+
# given
|
|
15
|
+
source = tmp_path / "source.txt"
|
|
16
|
+
destination = tmp_path / "destination"
|
|
17
|
+
source.write_text("Test content")
|
|
18
|
+
|
|
19
|
+
# when
|
|
20
|
+
success, copied_file = copy_file(str(source), str(destination))
|
|
21
|
+
|
|
22
|
+
# then
|
|
23
|
+
assert success is True
|
|
24
|
+
assert os.path.exists(copied_file)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_copy_file_failure():
|
|
28
|
+
# given
|
|
29
|
+
source = "/nonexistent/path/source.txt"
|
|
30
|
+
destination = "/destination/path"
|
|
31
|
+
|
|
32
|
+
# when
|
|
33
|
+
success, _ = copy_file(source, destination)
|
|
34
|
+
|
|
35
|
+
# then
|
|
36
|
+
assert success is False
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@pytest.mark.parametrize("path_to_run, expected_result", [
|
|
40
|
+
("/test/path", "Mocked result"),
|
|
41
|
+
("", "")
|
|
42
|
+
])
|
|
43
|
+
def test_run_analysis(monkeypatch, path_to_run, expected_result):
|
|
44
|
+
# given
|
|
45
|
+
params = ["--param1", "value1"]
|
|
46
|
+
output = "/output/path"
|
|
47
|
+
exe_path = "/exe/path"
|
|
48
|
+
|
|
49
|
+
def mock_func():
|
|
50
|
+
return expected_result
|
|
51
|
+
|
|
52
|
+
# Mock os.chdir to prevent changing directories during test
|
|
53
|
+
monkeypatch.setattr(os, 'chdir', lambda x: None)
|
|
54
|
+
# Mock os.getcwd to return a default path
|
|
55
|
+
monkeypatch.setattr(os, 'getcwd', lambda: "/mocked/path")
|
|
56
|
+
|
|
57
|
+
# when
|
|
58
|
+
result = run_analysis(path_to_run, params, mock_func, "Test Run", output, exe_path)
|
|
59
|
+
|
|
60
|
+
# then
|
|
61
|
+
assert result == expected_result
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def test_call_analysis_api_with_path():
|
|
65
|
+
# given
|
|
66
|
+
path_to_run = "/test/path"
|
|
67
|
+
str_run_start = "Test Run"
|
|
68
|
+
return_idx = -1
|
|
69
|
+
|
|
70
|
+
def mock_func():
|
|
71
|
+
return ["Result"]
|
|
72
|
+
|
|
73
|
+
# when
|
|
74
|
+
success, result = call_analysis_api(path_to_run, str_run_start, return_idx, mock_func)
|
|
75
|
+
|
|
76
|
+
# then
|
|
77
|
+
assert success is True
|
|
78
|
+
assert result == ["Result"]
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def test_call_analysis_api_without_path():
|
|
82
|
+
# given
|
|
83
|
+
path_to_run = ""
|
|
84
|
+
str_run_start = "Test Run"
|
|
85
|
+
return_idx = -1
|
|
86
|
+
|
|
87
|
+
def mock_func():
|
|
88
|
+
return ["Result"]
|
|
89
|
+
|
|
90
|
+
# when
|
|
91
|
+
success, result = call_analysis_api(path_to_run, str_run_start, return_idx, mock_func)
|
|
92
|
+
|
|
93
|
+
# then
|
|
94
|
+
assert success is True
|
|
95
|
+
assert result == []
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def test_create_scancodejson(monkeypatch):
|
|
99
|
+
# Given
|
|
100
|
+
|
|
101
|
+
# Mocking os.walk
|
|
102
|
+
def mock_os_walk(path):
|
|
103
|
+
return [("/mocked/absolute/path", ["dir1"], ["file1", "file2"])]
|
|
104
|
+
|
|
105
|
+
# Mocking write_scancodejson
|
|
106
|
+
def mock_write_scancodejson(dirname, basename, all_scan_item):
|
|
107
|
+
pass
|
|
108
|
+
|
|
109
|
+
# Mocking copy.deepcopy
|
|
110
|
+
def mock_deepcopy(obj):
|
|
111
|
+
return obj
|
|
112
|
+
|
|
113
|
+
# Mocking os.path.abspath
|
|
114
|
+
monkeypatch.setattr("os.path.abspath", lambda x: "/mocked/absolute/path")
|
|
115
|
+
|
|
116
|
+
# Mocking os.path.basename
|
|
117
|
+
monkeypatch.setattr("os.path.basename", lambda x: "mocked_parent")
|
|
118
|
+
monkeypatch.setattr("os.walk", mock_os_walk)
|
|
119
|
+
monkeypatch.setattr("fosslight_scanner.common.write_scancodejson", mock_write_scancodejson)
|
|
120
|
+
monkeypatch.setattr("copy.deepcopy", mock_deepcopy)
|
|
121
|
+
|
|
122
|
+
# Mocking FOSSLIGHT_DEPENDENCY and FOSSLIGHT_SOURCE
|
|
123
|
+
global FOSSLIGHT_DEPENDENCY, FOSSLIGHT_SOURCE
|
|
124
|
+
FOSSLIGHT_DEPENDENCY = "fosslight_dependency"
|
|
125
|
+
FOSSLIGHT_SOURCE = "fosslight_source"
|
|
126
|
+
|
|
127
|
+
# Mocking all_scan_item_origin
|
|
128
|
+
class AllScanItem:
|
|
129
|
+
def __init__(self):
|
|
130
|
+
self.file_items = {
|
|
131
|
+
FOSSLIGHT_DEPENDENCY: [],
|
|
132
|
+
FOSSLIGHT_SOURCE: []
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
all_scan_item_origin = AllScanItem()
|
|
136
|
+
ui_mode_report = "/mocked/ui_mode_report"
|
|
137
|
+
src_path = "/mocked/src_path"
|
|
138
|
+
|
|
139
|
+
# When
|
|
140
|
+
success, err_msg = create_scancodejson(all_scan_item_origin, ui_mode_report, src_path)
|
|
141
|
+
|
|
142
|
+
# Then
|
|
143
|
+
assert success is True
|
|
144
|
+
assert err_msg == ''
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def test_correct_scanner_result(monkeypatch):
|
|
148
|
+
# Given
|
|
149
|
+
class MockOSSItem:
|
|
150
|
+
def __init__(self, license, exclude=False):
|
|
151
|
+
self.license = license
|
|
152
|
+
self.exclude = exclude
|
|
153
|
+
|
|
154
|
+
class MockFileItem:
|
|
155
|
+
def __init__(self, source_name_or_path, oss_items, exclude=False):
|
|
156
|
+
self.source_name_or_path = source_name_or_path
|
|
157
|
+
self.oss_items = oss_items
|
|
158
|
+
self.exclude = exclude
|
|
159
|
+
|
|
160
|
+
class MockAllScanItem:
|
|
161
|
+
def __init__(self, file_items):
|
|
162
|
+
self.file_items = file_items
|
|
163
|
+
|
|
164
|
+
src_oss_item = MockOSSItem(license="MIT")
|
|
165
|
+
bin_oss_item = MockOSSItem(license="")
|
|
166
|
+
|
|
167
|
+
src_file_item = MockFileItem("path/to/source", [src_oss_item])
|
|
168
|
+
bin_file_item = MockFileItem("path/to/source", [bin_oss_item])
|
|
169
|
+
|
|
170
|
+
all_scan_item = MockAllScanItem({
|
|
171
|
+
"FOSSLIGHT_SOURCE": [src_file_item],
|
|
172
|
+
"FOSSLIGHT_BINARY": [bin_file_item]
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
# When
|
|
176
|
+
result = correct_scanner_result(all_scan_item)
|
|
177
|
+
# Then
|
|
178
|
+
assert len(result.file_items["FOSSLIGHT_BINARY"][0].oss_items) == 1
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
@pytest.mark.parametrize("source_name_or_path, expected", [
|
|
182
|
+
("project/venv/file.py", True),
|
|
183
|
+
("project/node_modules/file.js", True),
|
|
184
|
+
("project/Pods/file.m", True),
|
|
185
|
+
("project/Carthage/file.swift", True),
|
|
186
|
+
("project/src/file.py", False),
|
|
187
|
+
("project/venv/file.py", True),
|
|
188
|
+
])
|
|
189
|
+
def test_check_package_dir(source_name_or_path, expected):
|
|
190
|
+
result = check_package_dir(source_name_or_path)
|
|
191
|
+
# Then
|
|
192
|
+
assert result == expected
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
from fosslight_scanner.fosslight_scanner import run_scanner, download_source, init, run_main, run_dependency
|
|
2
|
+
from fosslight_util.oss_item import ScannerItem
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def test_run_dependency(tmp_path):
|
|
6
|
+
# given
|
|
7
|
+
path_to_analyze = tmp_path / "test_project"
|
|
8
|
+
output_file_with_path = tmp_path / "output_file"
|
|
9
|
+
params = "-m 'npm' -a 'activate_cmd' -d 'deactivate_cmd' -c 'custom_dir' -n 'app_name' -t 'token_value'"
|
|
10
|
+
path_to_exclude = ["node_modules"]
|
|
11
|
+
|
|
12
|
+
# Create the directory to analyze
|
|
13
|
+
path_to_analyze.mkdir(parents=True, exist_ok=True)
|
|
14
|
+
|
|
15
|
+
# when
|
|
16
|
+
result = run_dependency(str(path_to_analyze), str(output_file_with_path), params, path_to_exclude)
|
|
17
|
+
|
|
18
|
+
# then
|
|
19
|
+
# Check that result is an instance of ScannerItem
|
|
20
|
+
assert isinstance(result, ScannerItem), "Result should be an instance of ScannerItem."
|
|
21
|
+
|
|
22
|
+
# Check that result is not None
|
|
23
|
+
assert result is not None, "Result should not be None."
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def test_run_scanner(tmp_path):
|
|
27
|
+
# given
|
|
28
|
+
src_path = tmp_path / "test_src"
|
|
29
|
+
output_path = tmp_path / "output"
|
|
30
|
+
dep_arguments = ""
|
|
31
|
+
output_file = ['test_output']
|
|
32
|
+
output_extension = [".yaml"]
|
|
33
|
+
|
|
34
|
+
# Create necessary directories and files for the test
|
|
35
|
+
src_path.mkdir(parents=True, exist_ok=True)
|
|
36
|
+
output_path.mkdir(parents=True, exist_ok=True)
|
|
37
|
+
|
|
38
|
+
# Create a dummy source file in `src_path` to be scanned
|
|
39
|
+
test_file = src_path / "test_file.py"
|
|
40
|
+
test_file.write_text("# This is a test file\nprint('Hello, World!')")
|
|
41
|
+
|
|
42
|
+
# when
|
|
43
|
+
run_scanner(
|
|
44
|
+
src_path=str(src_path),
|
|
45
|
+
dep_arguments=dep_arguments,
|
|
46
|
+
output_path=str(output_path),
|
|
47
|
+
keep_raw_data=True,
|
|
48
|
+
run_src=True,
|
|
49
|
+
run_bin=False,
|
|
50
|
+
run_dep=False,
|
|
51
|
+
run_prechecker=False,
|
|
52
|
+
remove_src_data=False,
|
|
53
|
+
result_log={},
|
|
54
|
+
output_files=output_file,
|
|
55
|
+
output_extensions=output_extension,
|
|
56
|
+
num_cores=1,
|
|
57
|
+
path_to_exclude=[]
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# then
|
|
61
|
+
# Check if `src_path` and `output_path` still exist
|
|
62
|
+
assert src_path.is_dir(), "Source path should still exist."
|
|
63
|
+
assert output_path.is_dir(), "Output path should still exist."
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_download_source(tmp_path):
|
|
67
|
+
# given
|
|
68
|
+
link = "https://example.com/test_repo.git"
|
|
69
|
+
out_dir = tmp_path / "output"
|
|
70
|
+
|
|
71
|
+
# Create the necessary output directory
|
|
72
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
73
|
+
|
|
74
|
+
# when
|
|
75
|
+
success, temp_src_dir, oss_name, oss_version = download_source(str(link), str(out_dir))
|
|
76
|
+
|
|
77
|
+
# then
|
|
78
|
+
# Ensure the function completes successfully
|
|
79
|
+
assert isinstance(success, bool), "Function should return a boolean for success."
|
|
80
|
+
|
|
81
|
+
# If the function fails, ensure temp_src_dir is empty
|
|
82
|
+
if not success:
|
|
83
|
+
assert temp_src_dir == "", "temp_src_dir should be an empty string if download fails."
|
|
84
|
+
else:
|
|
85
|
+
# If the function succeeds, check temp_src_dir is a valid path
|
|
86
|
+
assert isinstance(temp_src_dir, str), "Temporary source directory should be a string."
|
|
87
|
+
assert str(temp_src_dir).startswith(str(out_dir)), "Temporary source directory should be within the output directory."
|
|
88
|
+
|
|
89
|
+
# Ensure oss_name and oss_version are strings
|
|
90
|
+
assert isinstance(oss_name, str), "OSS name should be a string."
|
|
91
|
+
assert isinstance(oss_version, str), "OSS version should be a string."
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def test_init(tmp_path):
|
|
95
|
+
# given
|
|
96
|
+
output_path = tmp_path / "output"
|
|
97
|
+
|
|
98
|
+
# Initialize global variables if necessary
|
|
99
|
+
global _output_dir, _log_file
|
|
100
|
+
_output_dir = "test_output" # Set to a default or test-specific value
|
|
101
|
+
_log_file = "test_log" # Set the name of the log file
|
|
102
|
+
|
|
103
|
+
# when
|
|
104
|
+
dir_created, output_root_dir, result_log = init(str(output_path))
|
|
105
|
+
|
|
106
|
+
# then
|
|
107
|
+
# Ensure that the output directory was created
|
|
108
|
+
assert dir_created is True, "The output directory should be created."
|
|
109
|
+
|
|
110
|
+
# Check if the output_root_dir is correct
|
|
111
|
+
assert output_root_dir == str(output_path), "Output root directory should match the given path."
|
|
112
|
+
|
|
113
|
+
# Check that the result_log is not None and is a dictionary
|
|
114
|
+
assert result_log is not None, "Result log should not be None."
|
|
115
|
+
assert isinstance(result_log, dict), "Result log should be a dictionary."
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def test_run_main(tmp_path):
|
|
119
|
+
# given
|
|
120
|
+
mode_list = ["source"]
|
|
121
|
+
path_arg = [str(tmp_path / "test_src")]
|
|
122
|
+
dep_arguments = []
|
|
123
|
+
output_file_or_dir = str(tmp_path / "output")
|
|
124
|
+
file_format = ['yaml']
|
|
125
|
+
url_to_analyze = ""
|
|
126
|
+
db_url = ""
|
|
127
|
+
|
|
128
|
+
# Create necessary directories and files for the test
|
|
129
|
+
(tmp_path / "test_src").mkdir(parents=True, exist_ok=True)
|
|
130
|
+
|
|
131
|
+
# when
|
|
132
|
+
result = run_main(
|
|
133
|
+
mode_list=mode_list,
|
|
134
|
+
path_arg=path_arg,
|
|
135
|
+
dep_arguments=dep_arguments,
|
|
136
|
+
output_file_or_dir=output_file_or_dir,
|
|
137
|
+
file_format=file_format,
|
|
138
|
+
url_to_analyze=url_to_analyze,
|
|
139
|
+
db_url=db_url,
|
|
140
|
+
hide_progressbar=True, # Disable progress bar for testing
|
|
141
|
+
keep_raw_data=True, # Keep raw data to avoid cleanup during test
|
|
142
|
+
num_cores=1,
|
|
143
|
+
correct_mode=True,
|
|
144
|
+
correct_fpath="",
|
|
145
|
+
ui_mode=False,
|
|
146
|
+
path_to_exclude=[]
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
# then
|
|
150
|
+
assert result is True
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner.egg-info/requires.txt
RENAMED
|
File without changes
|
{fosslight_scanner-2.1.9 → fosslight_scanner-2.1.11}/src/fosslight_scanner.egg-info/top_level.txt
RENAMED
|
File without changes
|