Skip to content

Commit 6c35c88

Browse files
authored
Merge pull request #10 from fosslight/develop
Add the -f option and change way to create output
2 parents c713f97 + 5375b36 commit 6c35c88

File tree

6 files changed

+137
-90
lines changed

6 files changed

+137
-90
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,19 @@ FOSSLight Scanner is run with the **fosslight** command.
5555
```
5656
-h Print help message
5757
-r Keep raw data
58-
-s <source_path> Path to analyze source
58+
-p <path> Path to analyze source
5959
-w <link> Link to be analyzaed can be downloaded by wget or git clone
6060
-o <output> Output Directory or file
61-
-d <dependency_path> Path to analyze dependencies
62-
-d <dependency_path> -a <additional_arg> (Using with -d option) Additional arguments for running dependency analysis
61+
-f <format> Output file format (excel, csv, opossum)
62+
-d <additional_arg> Additional arguments for running dependency analysis
6363
```
6464
- Ref. Additional arguments for running dependency analysis. See the [FOSSLight Dependency Guide][fd_guide] for instructions.
6565

6666
[fd_guide]: https://fosslight.org/fosslight-guide-en/scanner/2_dependency.html
6767

6868
### Ex 1. Local Source Analysis
6969
```
70-
$ fosslight -d /home/source_path -a "-a 'source /test/Projects/venv/bin/activate' -d 'deactivate'" -s /home/source_path
70+
$ fosslight -p /home/source_path -a "-a 'source /test/Projects/venv/bin/activate' -d 'deactivate'"
7171
```
7272

7373
### Ex 2. Download Link and analyze

requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ xlrd
55
openpyxl
66
progress
77
pyyaml
8-
fosslight_util>=1.3.3
9-
fosslight_dependency>=3.7.3
8+
fosslight_util>=1.3.4
9+
fosslight_dependency>=3.7.4

src/fosslight_scanner/_get_input.py

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,13 @@
99

1010

1111
def get_input(ask_msg, default_value=""):
12-
i = 0
13-
result = True
14-
for i in range(2):
15-
return_value = raw_input(
16-
ask_msg) if _PYTHON_VERSION < 3 else input(ask_msg)
17-
if return_value != "":
18-
break
19-
elif default_value != "":
20-
break
21-
else:
22-
i += 1
23-
if return_value == "" and default_value == "":
24-
result = False
25-
elif return_value == "" and default_value != "":
12+
13+
return_value = raw_input(
14+
ask_msg) if _PYTHON_VERSION < 3 else input(ask_msg)
15+
16+
if return_value == "" and default_value != "":
2617
return_value = default_value
27-
return result, return_value
18+
return return_value
2819

2920

3021
def ask_to_run(ask_msg):
@@ -38,23 +29,20 @@ def get_input_mode():
3829
global _PYTHON_VERSION
3930
_PYTHON_VERSION = sys.version_info[0]
4031

41-
_input_path_msg = "Please enter the path to analyze:"
42-
4332
url_to_analyze = ""
4433
src_path = ""
4534
dep_path = ""
4635
dep_arguments = ""
4736

48-
# 0. Select to analyze
49-
if ask_to_run("0. What are you going to analyze? (1/2)\n\
50-
\t1. Links that can be cloned by git or wget\n\
51-
2. Local source path\n"):
52-
success, url_to_analyze = get_input("Enter the link to analyze:", "")
37+
if ask_to_run("What are you going to analyze? (1/2)\n\
38+
1. Links that can be cloned by git or wget\n\
39+
2. Local source path\n"):
40+
url_to_analyze = get_input("Enter the link to analyze:", "")
5341
else:
54-
success, src_path = get_input(_input_path_msg, "")
42+
src_path = get_input("Please enter the path to analyze:", "")
5543
dep_path = src_path
5644

57-
success, dep_arguments = get_input(
45+
dep_arguments = get_input(
5846
"Please enter arguments for dependency analysis:", "")
5947

6048
return src_path, dep_path, dep_arguments, url_to_analyze

src/fosslight_scanner/_help.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
-p <source_path>\t\t\t Path to analyze source, dependency
1919
-w <link>\t\t\t\t Link to be analyzaed can be downloaded by wget or git clone
2020
-o <output>\t\t\t\t Output directory or file
21-
-d <dependency_argument> \t\t\t Additional arguments for running dependency analysis"""
21+
-f <format>\t\t\t\t Output file format (excel, csv, opossum)
22+
-d <dependency_argument> \t\t Additional arguments for running dependency analysis"""
2223

2324

2425
def print_help_msg():

src/fosslight_scanner/fosslight_scanner.py

Lines changed: 111 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -14,113 +14,167 @@
1414
from shutil import rmtree as rmdir
1515
from datetime import datetime
1616
from fosslight_source import run_scancode
17-
from fosslight_dependency.run_dependency_scanner import main as dep_main
17+
from fosslight_dependency.run_dependency_scanner import run_dependency_scanner
1818
from fosslight_util.download import cli_download_and_extract
1919
from ._get_input import get_input_mode
2020
from ._help import print_help_msg
2121
from fosslight_util.set_log import init_log
22-
from fosslight_util.write_excel import merge_excels
2322
from fosslight_util.timer_thread import TimerThread
2423
import fosslight_util.constant as constant
24+
from fosslight_util.output_format import write_output_file, check_output_format
2525

26-
_OUTPUT_FILE_PREFIX = "FOSSLight-Report_"
27-
_PKG_NAME = "fosslight_scanner"
26+
OUTPUT_EXCEL_PREFIX = "FOSSLight-Report_"
27+
OUTPUT_JSON_PREFIX = "Opossum_input_"
28+
PKG_NAME = "fosslight_scanner"
2829
logger = logging.getLogger(constant.LOGGER_NAME)
2930
warnings.simplefilter(action='ignore', category=FutureWarning)
3031
_output_dir = "fosslight_raw_data_"
3132
_log_file = "fosslight_log_"
3233
_start_time = ""
3334
_executed_path = ""
34-
_SRC_DIR_FROM_LINK_PREFIX = "fosslight_src_dir_"
35-
OUTPUT_FILE_EXTENSION = ".xlsx"
35+
SRC_DIR_FROM_LINK_PREFIX = "fosslight_src_dir_"
3636

3737

3838
def run_analysis(path_to_run, params, func, str_run_start, output, exe_path):
3939
# This function will be replaced by call_analysis_api().
4040
logger.info("## Start to run "+str_run_start)
41+
return_value = ""
4142
try:
4243
if path_to_run != "":
43-
logger.info("|--- Path to analyze :"+path_to_run)
44+
logger.info("|--- Path to analyze :" + path_to_run)
4445
os.chdir(output)
4546
sys.argv = params
46-
func()
47+
return_value = func()
4748
os.chdir(exe_path)
4849
else:
4950
logger.info("Analyzing path is missing...")
5051
except SystemExit:
5152
pass
5253
except Exception as ex:
5354
logger.error(str_run_start + ":" + str(ex))
55+
return return_value
5456

5557

56-
def call_analysis_api(path_to_run, str_run_start, func, *args):
58+
def call_analysis_api(path_to_run, str_run_start, return_idx, func, *args):
59+
# return_idx == -1 : Raw return value itself
5760
logger.info("## Start to run " + str_run_start)
61+
success = True
62+
result = []
5863
try:
5964
if path_to_run != "":
6065
logger.info("|--- Path to analyze :"+path_to_run)
61-
success, msg, result_list = func(*args)
62-
if not success:
63-
logger.warning(msg)
66+
result = func(*args)
6467
else:
6568
logger.info("Analyzing path is missing...")
6669
except SystemExit:
67-
pass
70+
success = False
6871
except Exception as ex:
72+
success = False
6973
logger.error(str_run_start + ":" + str(ex))
74+
try:
75+
if success:
76+
if result and return_idx >= 0:
77+
if len(result) > return_idx:
78+
result = result[return_idx]
79+
else:
80+
success = False
81+
except Exception as ex:
82+
logger.debug("Get return value:" + str(ex))
83+
success = False
84+
if not result:
85+
result = []
86+
return success, result
87+
7088

89+
def run_dependency(path_to_analyze, output_file_with_path, params=""):
90+
result_list = []
91+
92+
package_manager = ""
93+
pip_activate_cmd = ""
94+
pip_deactivate_cmd = ""
95+
output_custom_dir = ""
96+
app_name = ""
97+
github_token = ""
7198

72-
def set_sub_parameter(default_params, params): # For dependency
7399
try:
74100
if params != "":
75101
match_obj = re.findall(
76-
r'\s*(-\s*[a|d|m|c|p|v|o])\s*\'([^\']+)\'\s*', params)
102+
r'\s*(-\s*[a|d|m|c|n|t])\s*\'([^\']+)\'\s*', params)
77103
for param, value in match_obj:
78-
default_params.append(param)
79-
default_params.append(value)
104+
if param == "-m":
105+
package_manager = value
106+
elif param == "-a":
107+
pip_activate_cmd = value
108+
elif param == "-d":
109+
pip_deactivate_cmd = value
110+
elif param == "-c":
111+
output_custom_dir = value
112+
elif param == "-n":
113+
app_name = value
114+
elif param == "-t":
115+
github_token = value
116+
except Exception as ex:
117+
logger.warning("Set dependency Param:" + str(ex))
118+
119+
try:
120+
success, result = call_analysis_api(path_to_analyze, "Dependency Analysis",
121+
1, run_dependency_scanner,
122+
package_manager,
123+
os.path.abspath(path_to_analyze),
124+
output_file_with_path,
125+
pip_activate_cmd, pip_deactivate_cmd,
126+
output_custom_dir, app_name,
127+
github_token)
128+
if success:
129+
result_list = result.get('SRC_FL_Dependency')
80130
except Exception as ex:
81-
logger.warning("SET dependency Param:"+str(ex))
82-
return default_params
131+
logger.warning("Run dependency:"+str(ex))
132+
133+
if not result_list:
134+
result_list = []
135+
return result_list
83136

84137

85138
def run(src_path, dep_path, dep_arguments, output_path, remove_raw_data=True,
86-
remove_src_data=True, need_init=True, result_log={}, output_file=""):
139+
remove_src_data=True, need_init=True, result_log={}, output_file="", output_extension=""):
87140
try:
88141
success = True
142+
sheet_list = {}
89143
if need_init:
90144
success, final_excel_dir, result_log = init(output_path)
91145
else:
92146
final_excel_dir = output_path
147+
final_excel_dir = os.path.abspath(final_excel_dir)
148+
93149
if output_file == "":
94-
output_file = _OUTPUT_FILE_PREFIX + _start_time + OUTPUT_FILE_EXTENSION
150+
output_prefix = OUTPUT_EXCEL_PREFIX if output_extension != ".json" else OUTPUT_JSON_PREFIX
151+
output_file = output_prefix + _start_time
95152

96153
if success:
97154
output_files = {"SRC": "FL_Source",
98155
"BIN": "FL_Binary.xlsx",
99156
"DEP": "FL_Dependency.xlsx",
100-
"REUSE": "reuse.xml",
101-
"FINAL": output_file}
102-
if src_path != "":
103-
call_analysis_api(src_path, "Source Analysis",
104-
run_scancode.run_scan,
105-
os.path.abspath(src_path),
106-
os.path.join(_output_dir, output_files["SRC"]),
107-
False)
108-
if dep_path != "":
109-
run_analysis(dep_path,
110-
set_sub_parameter(["DEP",
111-
"-p", os.path.abspath(dep_path),
112-
"-o", os.path.join(_output_dir, output_files["DEP"])],
113-
dep_arguments),
114-
dep_main, "Dependency Analysis",
115-
_output_dir, _executed_path)
116-
117-
ouput_file = os.path.join(final_excel_dir, output_files["FINAL"])
118-
success, error_msg = merge_excels(_output_dir, ouput_file)
157+
"REUSE": "reuse.xml"}
158+
159+
success, result = call_analysis_api(src_path, "Source Analysis",
160+
2, run_scancode.run_scan,
161+
os.path.abspath(src_path),
162+
os.path.join(_output_dir, output_files["SRC"]),
163+
False, -1, True)
164+
if success:
165+
sheet_list["SRC_FL_Source"] = [scan_item.get_row_to_print() for scan_item in result]
166+
167+
result_list = run_dependency(dep_path, os.path.join(_output_dir, output_files["DEP"]), dep_arguments)
168+
sheet_list['SRC_FL_Dependency'] = result_list
169+
170+
output_file_without_ext = os.path.join(final_excel_dir, output_file)
171+
success, msg = write_output_file(output_file_without_ext, output_extension, sheet_list)
172+
119173
result_log["Result"] = success
120174
if success:
121-
result_log["FOSSLight-Report"] = ouput_file
175+
result_log["Output Path"] = final_excel_dir
122176
else:
123-
result_log["Result Message - Merge"] = error_msg
177+
result_log["Result Message - Merge"] = msg
124178
except Exception as ex:
125179
logger.error("Scanning:" + str(ex))
126180

@@ -141,12 +195,12 @@ def run(src_path, dep_path, dep_arguments, output_path, remove_raw_data=True,
141195
logger.debug("Error to remove temp files:"+str(ex))
142196

143197

144-
def run_after_download_source(link, out_dir, remove_raw_data, output_file=""):
198+
def run_after_download_source(link, out_dir, remove_raw_data, output_file="", output_extension=""):
145199
start_time = datetime.now().strftime('%Y%m%d_%H%M%S')
146200
try:
147201
success, final_excel_dir, result_log = init(out_dir)
148202
temp_src_dir = os.path.join(
149-
_output_dir, _SRC_DIR_FROM_LINK_PREFIX+start_time)
203+
_output_dir, SRC_DIR_FROM_LINK_PREFIX+start_time)
150204

151205
logger.info("Link to download :"+link)
152206
success, msg = cli_download_and_extract(
@@ -156,7 +210,7 @@ def run_after_download_source(link, out_dir, remove_raw_data, output_file=""):
156210
logger.info("Downloaded Dir:"+temp_src_dir)
157211
run(temp_src_dir, temp_src_dir,
158212
"", final_excel_dir, remove_raw_data, remove_raw_data, False,
159-
result_log, output_file)
213+
result_log, output_file, output_extension)
160214
else:
161215
logger.error("Download failed:" + msg)
162216
except Exception as ex:
@@ -184,7 +238,7 @@ def init(output_path=""):
184238

185239
log_dir = os.path.join(output_root_dir, "fosslight_log")
186240
logger, result_log = init_log(os.path.join(log_dir, _log_file + _start_time + ".txt"),
187-
True, logging.INFO, logging.DEBUG, _PKG_NAME)
241+
True, logging.INFO, logging.DEBUG, PKG_NAME)
188242

189243
return os.path.isdir(_output_dir), output_root_dir, result_log
190244

@@ -200,14 +254,15 @@ def main():
200254
url_to_analyze = ""
201255
_executed_path = os.getcwd()
202256
remove_raw_data = True
203-
output_dir = _executed_path
257+
output_path = _executed_path
204258
output_file = ""
205259
output_file_or_dir = ""
206260
show_progressbar = True
261+
file_format = ""
207262

208263
try:
209264
argv = sys.argv[1:]
210-
opts, args = getopt.getopt(argv, 'htrs:d:a:o:w:')
265+
opts, args = getopt.getopt(argv, 'htrs:d:a:o:w:f:p:')
211266
except getopt.GetoptError:
212267
print_help_msg()
213268

@@ -229,14 +284,14 @@ def main():
229284
remove_raw_data = False
230285
elif opt == "-t":
231286
show_progressbar = False
287+
elif opt == "-f":
288+
file_format = arg
232289

233290
try:
234-
if output_file_or_dir != "":
235-
if output_file_or_dir.endswith(OUTPUT_FILE_EXTENSION):
236-
output_file = Path(output_file_or_dir).name
237-
output_dir = os.path.dirname(os.path.abspath(output_file_or_dir))
238-
else:
239-
output_dir = os.path.abspath(output_file_or_dir)
291+
success, msg, output_path, output_file, output_extension = check_output_format(output_file_or_dir, file_format)
292+
if not success:
293+
logger.error(msg)
294+
return False
240295

241296
if not _cli_mode:
242297
src_path, dep_path, dep_arguments, url_to_analyze = get_input_mode()
@@ -246,10 +301,10 @@ def main():
246301
timer.start()
247302

248303
if url_to_analyze != "":
249-
run_after_download_source(url_to_analyze, output_dir, remove_raw_data, output_file)
304+
run_after_download_source(url_to_analyze, output_path, remove_raw_data, output_file, output_extension)
250305
elif src_path != "" or dep_path != "":
251306
run(src_path, dep_path,
252-
dep_arguments, output_dir, remove_raw_data, False, True, {}, output_file)
307+
dep_arguments, output_path, remove_raw_data, False, True, {}, output_file, output_extension)
253308
except Exception as ex:
254309
logger.warning(str(ex))
255310

0 commit comments

Comments
 (0)