Skip to content

Commit ceeb733

Browse files
committed
refactor: code clean up
1 parent f4ae01e commit ceeb733

7 files changed

Lines changed: 178 additions & 149 deletions

File tree

Dockerfile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ RUN apk add --no-cache python3 py3-pip && \
1212
# scip converter
1313
RUN curl -fLo scip-linux-amd64.tar.gz https://github.com/sourcegraph/scip/releases/download/v0.2.3/scip-linux-amd64.tar.gz \
1414
&& tar xf ./scip-linux-amd64.tar.gz \
15-
&& chmod +x ./scip \
16-
&& ./scip --help
15+
&& chmod +x ./scip
1716

1817
# java/kotlin/scala scip/lsif
1918
RUN apk add openjdk17 \

ai.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import openai
2+
3+
4+
def process_with_ai(raw: str) -> str:
5+
req = f"""
6+
You are a bot for helping code review.
7+
Standard csv report was generated from diff analysis tool.
8+
9+
Here is a csv report below for a specific commit.
10+
Evaluate it and indicate the most important parts which reviewers should care.
11+
Empty report means that there are no dangerous changes.
12+
13+
--- report start ---
14+
15+
{raw}
16+
17+
--- report end ---
18+
"""
19+
20+
completion = openai.ChatCompletion.create(
21+
model="gpt-3.5-turbo", messages=[{"role": "user", "content": req}]
22+
)
23+
return completion.choices[0].message.content

config.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
user_dir = "/github/workspace"
2+
support_langs = {"golang", "python", "java", "kotlin"}
3+
csv_result_file = "./output.csv"
4+
json_result_file = "./output.json"
5+
dot_result_file = "./output.dot"

diff.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from config import user_dir, csv_result_file, json_result_file, dot_result_file
2+
from utils import check_call
3+
4+
5+
def gen_diff(before_sha: str, after_sha: str):
6+
# gen diff
7+
set_safe_git_dir()
8+
check_call(
9+
[
10+
"srctx",
11+
"diff",
12+
"--src",
13+
user_dir,
14+
"--before",
15+
before_sha,
16+
"--after",
17+
after_sha,
18+
"--outputCsv",
19+
csv_result_file,
20+
"--outputJson",
21+
json_result_file,
22+
"--outputDot",
23+
dot_result_file,
24+
]
25+
)
26+
27+
28+
def set_safe_git_dir():
29+
check_call(["git", "config", "--global", "--add", "safe.directory", user_dir])

index.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import os
2+
3+
from loguru import logger
4+
5+
from diff import set_safe_git_dir
6+
from config import user_dir
7+
from utils import check_call
8+
9+
10+
def gen_index(lang: str):
11+
set_safe_git_dir()
12+
files = os.listdir(user_dir)
13+
logger.info(f"files: {files}")
14+
15+
if lang == "golang":
16+
gen_golang_index()
17+
elif lang == "python":
18+
gen_py_index()
19+
else:
20+
logger.error("no index mapping")
21+
return
22+
23+
24+
def gen_golang_index():
25+
check_call(["lsif-go", "-v"])
26+
27+
28+
def gen_java_and_kotlin_index():
29+
# https://sourcegraph.github.io/scip-java/docs/getting-started.html#run-scip-java-index
30+
check_call(["scip-java", "index", "--output", "index.scip"])
31+
# https://github.com/sourcegraph/scip/blob/main/docs/CLI.md
32+
check_call(["scip", "convert", "--from", "index.scip", "--to", "dump.lsif"])
33+
34+
35+
def gen_py_index():
36+
check_call(["lsif-py", ".", "--file", "./dump.lsif"])

main.py

Lines changed: 77 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -5,93 +5,88 @@
55
import sys
66

77
import openai
8-
import requests
98
from csvtomd import csv_to_table, md_table
109
from loguru import logger
1110

11+
from ai import process_with_ai
1212
from comment import send_comment
13+
from config import support_langs, csv_result_file, json_result_file, dot_result_file
14+
from diff import gen_diff
15+
from index import gen_index
1316
from object import FileList
1417

15-
user_dir = "/github/workspace"
16-
support_langs = {"golang", "python"}
17-
csv_result_file = "./output.csv"
18-
json_result_file = "./output.json"
19-
dot_result_file = "./output.dot"
2018

19+
def main():
20+
args = sys.argv[1:]
21+
lang = args[0]
22+
before_sha = args[1]
23+
after_sha = args[2]
24+
repo_token = args[3]
25+
issue_number = args[4]
26+
openai_api_key = args[5]
2127

22-
def gen_index(lang: str):
23-
set_safe_git_dir()
24-
files = os.listdir(user_dir)
25-
logger.info(f"files: {files}")
26-
27-
if lang == "golang":
28-
gen_golang_index()
29-
elif lang == "python":
30-
gen_py_index()
31-
else:
32-
logger.error("no index mapping")
28+
# check
29+
if lang not in support_langs:
30+
logger.error(f"lang not supported: {lang}, supported: {support_langs}")
31+
return
32+
if not before_sha or not after_sha:
33+
logger.warning("sha empty. Use default.")
34+
before_sha = "HEAD~1"
35+
after_sha = "HEAD"
36+
if not repo_token:
37+
logger.error("no repo token provided")
3338
return
3439

40+
# data prepare
41+
gen_index(lang)
42+
gen_diff(before_sha, after_sha)
3543

36-
def gen_golang_index():
37-
_check_call(["lsif-go", "-v"])
38-
39-
40-
def gen_py_index():
41-
_check_call(["lsif-py", ".", "--file", "./dump.lsif"])
42-
43-
44-
def _check_call(commands: list):
45-
subprocess.check_call(commands, cwd=user_dir)
46-
47-
48-
def set_safe_git_dir():
49-
_check_call(["git", "config", "--global", "--add", "safe.directory", user_dir])
44+
with open(csv_result_file, encoding="utf-8") as f:
45+
content = f.read()
5046

47+
ai_content = "-"
48+
if not openai_api_key:
49+
logger.warning("no openai api key found. Use raw data.")
50+
else:
51+
logger.info("process with openai")
52+
openai.api_key = openai_api_key
53+
ai_content = process_with_ai(content)
5154

52-
def gen_diff(before_sha: str, after_sha: str):
53-
# gen diff
54-
set_safe_git_dir()
55-
_check_call(
56-
[
57-
"srctx",
58-
"diff",
59-
"--src",
60-
user_dir,
61-
"--before",
62-
before_sha,
63-
"--after",
64-
after_sha,
65-
"--outputCsv",
66-
csv_result_file,
67-
"--outputJson",
68-
json_result_file,
69-
"--outputDot",
70-
dot_result_file,
71-
]
72-
)
55+
# todo: add to feedback?
56+
logger.info(f"ai resp: {ai_content}")
7357

58+
repo_name = os.getenv("GITHUB_REPOSITORY")
59+
process_json(json_result_file, csv_result_file)
60+
diff_desc = f"Start from {before_sha} to {after_sha}."
61+
summary = get_summary(json_result_file)
62+
md_table_raw = convert_csv_to_md(csv_result_file)
7463

75-
def process_with_ai(raw: str) -> str:
76-
req = f"""
77-
You are a bot for helping code review.
78-
Standard csv report was generated from diff analysis tool.
64+
# graph
65+
svg_bytes = dot_to_svg(dot_result_file)
66+
# todo: have no idea about how to display this graph in comment without any extra servers
7967

80-
Here is a csv report below for a specific commit.
81-
Evaluate it and indicate the most important parts which reviewers should care.
82-
Empty report means that there are no dangerous changes.
68+
final_content = f"""
69+
## [DiffCtx](https://github.com/williamfzc/diffctx) Report
8370
84-
--- report start ---
71+
{diff_desc}
8572
86-
{raw}
73+
{summary}
8774
88-
--- report end ---
75+
{md_table_raw}
8976
"""
77+
logger.info(f"final comment: {final_content}")
9078

91-
completion = openai.ChatCompletion.create(
92-
model="gpt-3.5-turbo", messages=[{"role": "user", "content": req}]
93-
)
94-
return completion.choices[0].message.content
79+
# feedback
80+
if not issue_number:
81+
logger.warning(
82+
"This action is not triggered by a PR. Will not leave any comments."
83+
)
84+
return
85+
send_comment(repo_token, repo_name, int(issue_number), final_content)
86+
87+
# # code comments
88+
# lines = parse_file_as(typing.List[LineStat], pathlib.Path(json_result_file))
89+
# send_code_comments(repo_token, after_sha, repo_name, int(issue_number), lines)
9590

9691

9792
def convert_csv_to_md(csv_file) -> str:
@@ -112,9 +107,15 @@ def format_percentage(numerator, denominator):
112107
return f"{percent:.2f}% ({numerator}/{denominator})"
113108

114109
for file in file_list.files:
115-
file.affectedLinePercentRepr = format_percentage(file.affectedLines, file.totalLines)
116-
file.affectedFunctionPercentRepr = format_percentage(file.affectedFunctions, file.totalFunctions)
117-
file.affectedReferencePercentRepr = format_percentage(file.affectedReferences, file.totalReferences)
110+
file.affectedLinePercentRepr = format_percentage(
111+
file.affectedLines, file.totalLines
112+
)
113+
file.affectedFunctionPercentRepr = format_percentage(
114+
file.affectedFunctions, file.totalFunctions
115+
)
116+
file.affectedReferencePercentRepr = format_percentage(
117+
file.affectedReferences, file.totalReferences
118+
)
118119

119120
file_list.files = sort_files_by_impact(file_list.files)
120121

@@ -124,7 +125,7 @@ def format_percentage(numerator, denominator):
124125
"AffectedFunctions",
125126
"AffectedReferences",
126127
]
127-
with open(output_csv, "w", newline='') as f:
128+
with open(output_csv, "w", newline="") as f:
128129
writer = csv.DictWriter(f, fieldnames=cols)
129130
writer.writeheader()
130131

@@ -149,10 +150,12 @@ def get_summary(input_json) -> str:
149150
affected_functions = sum([each.affectedFunctions for each in file_list.files])
150151
affected_refs = sum([each.affectedReferences for each in file_list.files])
151152

152-
return f"This commit directly influences {affected_files} files, " \
153-
f"{affected_lines} lines, " \
154-
f"{affected_functions} functions. " \
155-
f"Indirectly influences {affected_refs} functions. "
153+
return (
154+
f"This commit directly influences {affected_files} files, "
155+
f"{affected_lines} lines, "
156+
f"{affected_functions} functions. "
157+
f"Indirectly influences {affected_refs} functions. "
158+
)
156159

157160

158161
def dot_to_svg(dot_file):
@@ -167,78 +170,5 @@ def sort_key(f):
167170
return sorted(files, key=sort_key, reverse=True)
168171

169172

170-
def main():
171-
args = sys.argv[1:]
172-
lang = args[0]
173-
before_sha = args[1]
174-
after_sha = args[2]
175-
repo_token = args[3]
176-
issue_number = args[4]
177-
openai_api_key = args[5]
178-
179-
# check
180-
if lang not in support_langs:
181-
logger.error(f"lang not supported: {lang}, supported: {support_langs}")
182-
return
183-
if not before_sha or not after_sha:
184-
logger.warning("sha empty. Use default.")
185-
before_sha = "HEAD~1"
186-
after_sha = "HEAD"
187-
if not repo_token:
188-
logger.error("no repo token provided")
189-
return
190-
191-
# data prepare
192-
gen_index(lang)
193-
gen_diff(before_sha, after_sha)
194-
195-
with open(csv_result_file, encoding="utf-8") as f:
196-
content = f.read()
197-
198-
ai_content = "-"
199-
if not openai_api_key:
200-
logger.warning("no openai api key found. Use raw data.")
201-
else:
202-
logger.info("process with openai")
203-
openai.api_key = openai_api_key
204-
ai_content = process_with_ai(content)
205-
206-
# todo: add to feedback?
207-
logger.info(f"ai resp: {ai_content}")
208-
209-
repo_name = os.getenv("GITHUB_REPOSITORY")
210-
process_json(json_result_file, csv_result_file)
211-
diff_desc = f"Start from {before_sha} to {after_sha}."
212-
summary = get_summary(json_result_file)
213-
md_table_raw = convert_csv_to_md(csv_result_file)
214-
215-
# graph
216-
svg_bytes = dot_to_svg(dot_result_file)
217-
# todo: have no idea about how to display this graph in comment without any extra servers
218-
219-
final_content = f"""
220-
## [DiffCtx](https://github.com/williamfzc/diffctx) Report
221-
222-
{diff_desc}
223-
224-
{summary}
225-
226-
{md_table_raw}
227-
"""
228-
logger.info(f"final comment: {final_content}")
229-
230-
# feedback
231-
if not issue_number:
232-
logger.warning(
233-
"This action is not triggered by a PR. Will not leave any comments."
234-
)
235-
return
236-
send_comment(repo_token, repo_name, int(issue_number), final_content)
237-
238-
# # code comments
239-
# lines = parse_file_as(typing.List[LineStat], pathlib.Path(json_result_file))
240-
# send_code_comments(repo_token, after_sha, repo_name, int(issue_number), lines)
241-
242-
243173
if __name__ == "__main__":
244174
main()

utils.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import subprocess
2+
3+
from config import user_dir
4+
5+
6+
def check_call(commands: list):
7+
subprocess.check_call(commands, cwd=user_dir)

0 commit comments

Comments
 (0)