Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 8358601

Browse files
Merge pull request #115 from codefuse-ai/cxy_develop
添加--sarif选项,可将执行结果转为sarif报告
2 parents e919b45 + 00c1773 commit 8358601

File tree

2 files changed

+197
-0
lines changed

2 files changed

+197
-0
lines changed

‎cli/query/run.py

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import json
22
import logging
3+
import os.path
34
import re
45
import shutil
56
import sqlite3
@@ -275,6 +276,190 @@ def merge_execute(args, gdl_list, timeout):
275276
f.write(json.dumps(content, indent=4))
276277

277278

279+
def json_to_sarif(sarif_data, json_data):
280+
rules_dict = dict()
281+
for bug in json_data:
282+
# ruleName
283+
if "ruleName" in bug:
284+
rule_id = bug.get("ruleName")
285+
else:
286+
return False
287+
# filePath
288+
if "filePath" in bug:
289+
file_path = bug.get("filePath")
290+
else:
291+
return False
292+
# startLine
293+
if "startLine" in bug:
294+
start_line = bug.get("startLine")
295+
else:
296+
return False
297+
# ruleDescription
298+
if "ruleDescription" in bug:
299+
rule_description = bug.get("ruleDescription")
300+
else:
301+
return False
302+
# bug message
303+
if "message" in bug:
304+
message = bug.get("message")
305+
else:
306+
message = rule_description
307+
level = "error"
308+
if "level" in bug:
309+
level = bug.get("level").lower()
310+
if rule_id not in rules_dict:
311+
rule_index = len(rules_dict)
312+
rules_dict[rule_id] = rule_index
313+
res = {
314+
"id": rule_id,
315+
"name": rule_id,
316+
"shortDescription": {
317+
"text": rule_description
318+
},
319+
"fullDescription": {
320+
"text": rule_description
321+
},
322+
"defaultConfiguration": {
323+
"level": level
324+
}
325+
}
326+
sarif_data["runs"][0]["tool"]["driver"]["rules"].append(res)
327+
else:
328+
rule_index = rules_dict[rule_id]
329+
thread_flow_locations = []
330+
thread_flow_locations.append({
331+
"location": {
332+
"physicalLocation": {
333+
"artifactLocation": {
334+
"uri": file_path
335+
},
336+
"region": {
337+
"startLine": start_line,
338+
"endLine": start_line,
339+
"snippet": {
340+
"text": ""
341+
}
342+
},
343+
"contextRegion": {
344+
"startLine": start_line,
345+
"endLine": start_line,
346+
"snippet": {
347+
"text": ""
348+
}
349+
}
350+
},
351+
"message": {
352+
"text": message
353+
}
354+
}
355+
})
356+
sarif_data["runs"][0]["results"].append({
357+
"ruleId": rule_id,
358+
"ruleIndex": rule_index,
359+
"level": "error" if bug.get("Importance", "").lower() == "high" else "warning",
360+
"message": {
361+
"text": message
362+
},
363+
"locations": [
364+
{
365+
"physicalLocation": {
366+
"artifactLocation": {
367+
"uri": thread_flow_locations[0]["location"]["physicalLocation"]["artifactLocation"][
368+
"uri"]
369+
},
370+
"region": {
371+
"startLine": thread_flow_locations[0]["location"]["physicalLocation"]["region"][
372+
"startLine"],
373+
"endLine": thread_flow_locations[0]["location"]["physicalLocation"]["region"][
374+
"startLine"],
375+
"snippet": {
376+
"text": ""
377+
}
378+
},
379+
"contextRegion": {
380+
"startLine": thread_flow_locations[0]["location"]["physicalLocation"]["region"][
381+
"startLine"],
382+
"endLine": thread_flow_locations[0]["location"]["physicalLocation"]["region"][
383+
"startLine"],
384+
"snippet": {
385+
"text": ""
386+
}
387+
}
388+
},
389+
"message": {
390+
"text": message
391+
},
392+
}
393+
],
394+
"codeFlows": [
395+
{
396+
"threadFlows": [
397+
{
398+
"locations": thread_flow_locations
399+
}
400+
]
401+
}
402+
]
403+
})
404+
return True
405+
406+
407+
def output_to_sarif(args):
408+
# 脚本收集
409+
godel_path_list = list()
410+
for godel_dir in args.godel_dir:
411+
godel_path_list += get_files(godel_dir, ".gdl")
412+
godel_path_list += get_files(godel_dir, ".gs")
413+
sarif_data = {
414+
"version": "2.1.0",
415+
"$schema": "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0.json",
416+
"runs": [
417+
{
418+
"tool": {
419+
"driver": {
420+
"name": "Custom Tool",
421+
"informationUri": "https://example.com",
422+
"rules": []
423+
}
424+
},
425+
"results": []
426+
}
427+
]
428+
}
429+
# 获取脚本对应的结果并写入sarif报告中
430+
for godel_query_script in godel_path_list:
431+
output = str(Path(args.output).expanduser().resolve() / (godel_query_script.stem + "." + args.format))
432+
if not os.path.exists(output):
433+
logging.warning("%s does not exist, it seems that there is a problem with the %s, please check the script",
434+
output, str(godel_query_script))
435+
continue
436+
with open(output, "r") as f:
437+
output_json = json.load(f)
438+
# 脚本单输出直接转
439+
if isinstance(output_json, list):
440+
status = json_to_sarif(sarif_data, output_json)
441+
if not status:
442+
logging.warning("The output of %s needs to include filePath, startLine, ruleName,ruleDescription. it "
443+
"can not trans to sarif", godel_query_script)
444+
else:
445+
logging.info("%s trans to sarif success", godel_query_script)
446+
# 脚本多输出分别转过去
447+
else:
448+
trans = True
449+
for key, value in output_json.items():
450+
status = json_to_sarif(sarif_data, value)
451+
if not status:
452+
logging.warning("The output of %s %s needs to include filePath, startLine, "
453+
"ruleName,ruleDescription. it can not trans to sarif", godel_query_script, key)
454+
trans = False
455+
if trans:
456+
logging.info("%s trans to sarif success", godel_query_script)
457+
458+
output = str(Path(args.output).expanduser().resolve() / ("sparrow-cli-report.sarif"))
459+
with open(output, "w") as f:
460+
f.write(json.dumps(sarif_data, indent=4))
461+
462+
278463
def query_run(args):
279464
# conf 检查
280465
if not conf_check(args):
@@ -295,6 +480,8 @@ def query_run(args):
295480
logging.warning("When merging execution, please make sure that single reservation of functions or classes "
296481
"with the same name will not affect the execution results.")
297482
merge_execute(args, godel_path_list, args.timeout)
483+
if args.sarif:
484+
output_to_sarif(args)
298485
return
299486
status = 1
300487
# 目前先各自执行:
@@ -317,6 +504,8 @@ def query_run(args):
317504
logging.error("Task %s is %s, result is %s, execution time is %.2fs.",
318505
str(godel_query_script), "fail", "null", time.time() - start_time)
319506
logging.error("%s execute error, please check by log", str(godel_query_script))
507+
if args.sarif:
508+
output_to_sarif(args)
320509
if status == 1:
321510
logging.info("run success")
322511
else:

‎cli/sparrow-cli.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ def parse_args():
7676
subparser_query_run.add_argument("--gdl", '-gdl', required=True, nargs="*", dest="godel_dir",
7777
help='The location of the godel script that needs to execute')
7878
subparser_query_run.add_argument('--verbose', action='store_true', help='Enable verbose mode')
79+
subparser_query_run.add_argument('--sarif', action='store_true', help='Turn on the sarif report option, all '
80+
'outputs will be merged into one sarif, '
81+
'and the output result will be '
82+
'sparrow-cli-report.sarif in the output '
83+
'directory. The original godel script '
84+
'output must contain information such as '
85+
'filePath, startLine, ruleName, '
86+
'ruleDescription, etc.')
7987
subparser_query_run.add_argument('--merge', '-m', action='store_true', help='Combined execution of multiple '
8088
'scripts,Only one function and class '
8189
'with the same name in the script '

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /